ZOJ 1655 Transport Goods (杀入ranklist1000,撒花)

这可以归结为单终点最短路径,然后变为单源的。

 

每个城市的货物运送到首都之后都不同程度减少,是原来货物的dist[i]倍。刚开始dist初始化为0,起点为1,每走一段路就乘以这段路的(1-rate),每次总是把最大的放到集合S中,英文之后的dist都比他小,不可能改变她的值。最后每个点的货物量乘以剩余率就OK!~

 

#include<stdio.h> #include<math.h> const double eps = 1e-6; int N,M,i,j; int now,from,to; double max,sum,rate; double dist[111]; int flag[111]; double mat[111][111]; int goods[111]; int main(void) { while( scanf("%d%d",&N,&M) != EOF ) { for( i = 1; i < N; i++ ) scanf("%d",&goods[i]); for( i = 1; i <= N; i++ ) { dist[i] = 0; flag[i] = 0; for( j = 1; j <= N; j++ ) mat[i][j] = 0; } for( i = 1; i <= M; i++ ) { scanf("%d%d%lf",&from,&to,&rate); if( (mat[from][to]+eps) < 1- rate ) mat[from][to] = mat[to][from] = 1 - rate; } dist[N] = 1; flag[now = N] = 1; for( i = 1; i < N; i++ ) { for( j = 1; j <= N; j++ ) if( !flag[j] && (dist[j]+eps) < dist[now]*mat[j][now] ) dist[j] = dist[now]*mat[j][now]; for( j = 1,max = 0; j <= N; j++ ) if( !flag[j] && dist[j] > (max + eps) ) max = dist[now=j]; flag[now] = 1; } for(i = 1,sum = 0;i < N;i++ ) sum += dist[i]*goods[i]; printf("%.2f/n",sum); } return 0; }

你可能感兴趣的:(ZOJ 1655 Transport Goods (杀入ranklist1000,撒花))