题意:HERO过的首都需要货物,需要从其他的城市吧货物送到首都,每条道路都会需要消耗一定比例的货物,问最多能送多少货物到首都。
思路:如果每个点的比例是1,到达首都的比例就是经过的路径的(1-消耗比)的乘积,反正是无向的,所以可以反过来推,首都的货物比是1,而到达每座
城市的货物就是所经过的路径(1-消耗比)的乘积,则由此可见,我们可以求首都到任意城市的最大比值;最后把每个点的最大比值乘以每个点的货物加起来
即是结果。
#include<stdio.h> #include<string.h> const int maxn = 150; const double lep = 1e-8; double map[maxn][maxn]; int vis[maxn]; double dis[maxn]; int w[maxn]; int n,m; void init() { memset(vis,0,sizeof(vis)); memset(dis,0,sizeof(dis)); for(int i=0;i<=n;i++) { for(int j =0;j<=n;j++) map[i][j] = -1; } } double DIJ() // 求每座城市送物资的最大比值; { int i,j; int u = n; dis[u] = 1; vis[u] = 1; for(i=1;i<=n;i++) { for(j=1;j<n;j++) { if(!vis[j] && dis[j] < dis[u] * map[u][j]) { dis[j] = dis[u] * map[u][j]; } } double max = 0; for(j=1;j<n;j++) { if(!vis[j] && dis[j] - max > lep) { max = dis[j]; u = j; } } vis[u] =1; } double ans = 0; for(i= 1; i<n;i++) ans += w[i] * dis[i]; return ans; } int main() { int i; while(~scanf("%d%d",&n,&m)) { init(); for(i=1;i<n;i++) scanf("%d",&w[i]); w[n]= 0; for(i=0;i<m;i++) { int a,b; double c; scanf("%d%d%lf",&a,&b,&c); if(map[a][b] < (1 - c) ) { map[a][b] = map[b][a] = 1-c; // printf("%lf\n",map[a][b]); } } printf("%.2lf\n",DIJ()); } return 0; } /* 5 6 10 10 10 10 1 3 0 1 4 0 2 3 0 2 4 0 3 5 0 4 5 0 */
zoj1655 最短路变形
时间: 2024-10-14 15:09:28