zoj 1655 transport goods

题解
求一个最长路,以首都(n)为起点用dijkstra跑最短路
路的权值为1-c 源点n到其他的点贡献就是最长路的贡献乘以该点的贡献
然后把n-1个点的贡献一起加起来就是所要求的值

链接zoj 1655

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

#include <cstdio>
using namespace std;

const int maxn=1010;
bool vis[maxn];
double cost[maxn][maxn],lowcost[maxn];
int n,m;
void (int beg)
{
for (int i=0;i<n;i++)
{
lowcost[i]=0;
vis[i]=false;
}
lowcost[beg]=1;
for (int j=0;j<n;j++)
{
int k=-1;
double Min=-1;
for (int i=0;i<n;i++)
{
if(!vis[i] && lowcost[i]>Min)
{
Min=lowcost[i];
k=i;
}
}
if(k==-1) break;
vis[k]=true;
for (int i=0;i<n;i++)
{
if(!vis[i] && lowcost[k]*cost[k][i]>lowcost[i])
{
lowcost[i]=lowcost[k]*cost[k][i];
}
}
}
}
int a[maxn];

int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
for (int i=0;i<n-1;i++)
scanf("%d",&a[i]);
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
cost[i][j]=-1;
for (int i=0;i<m;i++)
{
int a,b;
double c;
scanf("%d%d%lf",&a,&b,&c);
a--,b--;
if(cost[a][b]<1.0-c)
{
cost[a][b]=1.0-c;
cost[b][a]=1.0-c;
}
}
dijkstra(n-1);
double ans=0;
for (int i=0;i<n-1;i++)
{
ans+=a[i]*1.0*lowcost[i];
}
printf("%.2fn",ans);
}
return 0;
}