题目:从第一个节点到底n个节点传递信息,请选择一条安全概率最高的。
输入:第一行 T 表示有T组测试数据(1<=T<=8)
对于每组测试数据:
第一行 n,m 分别表示节点数和通道数(1<=n<=10000 1<=m<=50000)
接下来有m行 每行 i,j,p;表示节点i,j间有一条通道,p%表示安全的概率
输出:每组数据输出一个实数,即从第一个节点到节点n的最高概率,精确到小数点的后6位
样例:输入
1
5 7
5 2 100
3 5 80
2 3 70
2 1 50
3 4 90
4 1 85
3 1 70
输出:61.200000
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define N 0 using namespace std; int n,m; int vis[50005]; double dis[50005],a[10005][10005]; void dij(int v0) { int i,j; memset(vis,0,sizeof(vis)); for(i=1;i<=m;i++) { if(i==v0) dis[i]=0; else dis[i]=a[v0][i]; } vis[v0]=1; for(i=2;i<n;i++) { int t; double x=N; for(j=1;j<=n;j++) { if(!vis[j]&&dis[j]>x) { t=j; x=dis[j]; } } vis[t]=1; for(j=1;j<=n;j++) { if(!vis[j]&&dis[j]<dis[t]*a[t][j]) dis[j]=dis[t]*a[t][j]; } } } int main() { int T; scanf("%d",&T); while(T--){ int i,j,x,y,z; double z1; scanf("%d %d",&n,&m); memset(a,N,sizeof(a)); for(i=1;i<=m;i++) { scanf("%d %d %d",&x,&y,&z); z1=z/100.0; a[x][y]=max(a[x][y],z1); a[y][x]=max(a[y][z],z1); } dij(1); dis[n]=dis[n]*100; printf("%.6f",dis[n]); } return 0; }
spfa算法 #include <stdio.h> #include <queue> using namespace std; struct Node { int to,next; double w; }edge[50005*2]; int head[10005]; int used[10005]; double dist[10005]; int num,n,m; void add(int u,int v,int e) { edge[num].to=v; edge[num].w=(double)e/100; edge[num].next=head[u]; head[u]=num++; } void Spfa(int star) { int u,v,i; queue<int> Q; for(i=1;i<=n;i++) dist[i]=0; dist[star]=1; used[star]=1; Q.push(star); while(!Q.empty()) { u=Q.front(); Q.pop(); used[u]=0; for(i=head[u];i!=-1;i=edge[i].next) { v=edge[i].to; if(dist[v]<dist[u]*edge[i].w) { dist[v]=dist[u]*edge[i].w; if(used[v]==0) used[v]=1,Q.push(v); } } } } int main() { int T,u,v,e,i; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); if(n==0&&m==0) break; for(i=1;i<=n;i++) head[i]=-1,used[i]=0; num=0; while(m--) { scanf("%d%d%d",&u,&v,&e); add(u,v,e); add(v,u,e); } Spfa(1); printf("%lf\n",dist[n]*100); } return 0; }