https://lydsy.com/JudgeOnline/problem.php?id=4055

题解

观察题目要我们求的东西:

\[ans[k]=\sum_{i}\sum_j \frac{a_i*a_j*f_k[i][j]}{f[i][j]}
\]

然后我们可以先枚举i,然后对于那个带限制的最短路部分,我们可以把贡献拆成两部分来计算。

\[ans[k]=\sum_{i}a_i*f[i][k]\sum_j\frac{a_j*f[k][j]}{f[i][j]}
\]

由于我们还要满足最短路的限制,所以我们可以先对每个i建出以i为源点的最短路\(DAG\)然后再\(DAG\)上维护后面的求和就可以了,这样可以保证是合法的。

Warning

维护f数组时注意一开始为了转移将\(f[i][i]=1\),最后做完了记得清空。

代码

#include<bits/stdc++.h>
#define N 1009
#define M 4009
#define mm make_pair
using namespace std;
typedef long long ll;
int head[N],tot,dis[N],du[N],n,m;
bool vis[N];
vector<int>vec[N];
vector<int>::iterator it;
priority_queue<pair<int,int> >q;
long double cnt[N][N],g[N],ans[N],a[N];
inline ll rd(){
ll x=0;char c=getchar();bool f=0;
while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f?-x:x;
}
struct edge{
int n,to,l;double f;
}e[M<<1];
inline void add(int u,int v,int l,double f){
e[++tot].n=head[u];e[tot].to=v;head[u]=tot;e[tot].f=f;e[tot].l=l;
}
inline void link(int i,int u){
vec[u].push_back(i);du[e[i].to]++;
}
inline void dij(int s){
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
q.push(mm(0,s));cnt[s][s]=1;dis[s]=0;
while(!q.empty()){
int u=q.top().second;q.pop();
if(vis[u])continue;
vis[u]=1;
for(int i=head[u];i;i=e[i].n){
int v=e[i].to;
if(dis[v]>dis[u]+e[i].l){
dis[v]=dis[u]+e[i].l;
cnt[s][v]=cnt[s][u]*e[i].f;
q.push(mm(-dis[v],v));
}
else if(dis[v]==dis[u]+e[i].l)cnt[s][v]+=cnt[s][u]*e[i].f;
}
}
}
inline void topsort(int s){
memset(g,0,sizeof(g));
queue<int>q;
for(int i=1;i<=n;++i)if(!du[i])q.push(i);
while(!q.empty()){
int u=q.front();q.pop();
ans[u]+=a[s]*cnt[s][u]*g[u];
g[u]+=a[u]/cnt[s][u];
for(it=vec[u].begin();it!=vec[u].end();++it){
int i=*it,v=e[i].to;
if(!--du[v])q.push(v);
g[v]+=g[u]*e[i].f;
}
}
}
int main(){
n=rd();m=rd();
for(int i=1;i<=n;++i)a[i]=rd();
int u,v,l;double f;tot=1;
for(int i=1;i<=m;++i){
u=rd();v=rd();l=rd();scanf("%lf",&f);
add(u,v,l,f);add(v,u,l,f);
}
for(int s=1;s<=n;++s){
dij(s);
cnt[s][s]=0;
for(int u=1;u<=n;++u)
for(int i=head[u];i;i=e[i].n)if(dis[u]+e[i].l==dis[e[i].to])link(i^1,e[i].to);
topsort(s);
for(int u=1;u<=n;++u)vec[u].clear();
}
for(int i=1;i<=n;++i)printf("%.8Lf\n",ans[i]);
return 0;
}

最新文章

  1. Utility1:Overview
  2. 如何实现一个malloc
  3. asp.net夜话之十一:web.config详解
  4. 跨站脚本攻击(XSS)
  5. Linux平台Makefile文件的编写基础篇(转)
  6. yaml 1.6 操作
  7. 转:JavaScript函数式编程(一)
  8. C语言中头文件&lt;stdio.h&gt;中的#ifndef _STDIO_H_
  9. Webserver管理系列:3、Windows Update
  10. ural1037 Memory Management
  11. 1、安卓数据存储机制——sharedPreference
  12. thinkinginjava学习笔记02_对象
  13. [特别公告]RDIFramework.NET微信公众号迁移通知
  14. String 常用方法
  15. MVC part4
  16. 剑指offer六之求旋转数组的最小数字
  17. Python3之pymysql导入mysql
  18. Windows2008安装WebSphere 6.1提示此安装程序不能在图形方式中运行
  19. Spring Boot统一异常处理方案示例
  20. linux 服务器删除大文件之后不释放存储空间的解决办法

热门文章

  1. 16/7/8_PHP-字符串介绍
  2. vue组件生命周期
  3. 3 Vue.js基础
  4. python3.5+django2.0快速入门(二)
  5. Flutter修改状态栏颜色以及字体颜色
  6. hdu-1281.棋盘游戏(二分图匹配 + 二分图关键点查询)
  7. 通过总线机制实现自动刷新客户端配置(Consul,Spring Cloud Config,Spring Cloud Bus)
  8. Golang环境配置
  9. 解决 myEclipse与tomcat 不同步的问题
  10. .NetCore模拟Postman的BasicAuth生成Authrization