【Step1】【SPFA】poj2472-106 miles to Chicago
题目大意
在输入数据中,有多组测试。
每组测试第一行为n,m表示有n个点,m条边
接下来m行,每行a,b,c表示a之间b的双向道路,安全通过的概率为c(百分数,省略百分号)
求从1到n的安全通过的最大概率。
当n=0时,输入结束。
这道题看起来非常奇妙,求最大概率好像是最短路反过来,这其实也可以用SPFA求解。
如果我的路径是A->B->C,AB之间的概率为x,BC之间的概率为y,那么我们A->C的概率就是x*y,所以SPFA的更新方程为:
f[y]<f[x]*a[i].d
小问题
f数组记得初始化为0,然后刚开始输入的概率记得先除100,最后再乘100,否则概率越乘越大。
代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstdlib> #include<cstring> struct qq{ int x,y,next; double d; }a[10005]; double f[105]; bool tf[105]; int first[105]; int q[105]; int n,m,len; void make_l(int x,int y,double d) { len++; a[len].x=x; a[len].y=y; a[len].d=d; a[len].next=first[x]; first[x]=len; } int main() { while(1) { scanf("%d",&n); if(n==0)break; scanf("%d",&m); memset(first,0,sizeof(first));len=0; for(int i=1;i<=m;i++) { int x,y; double d; scanf("%d %d %lf",&x,&y,&d); make_l(x,y,d/100.0); make_l(y,x,d/100.0); } for(int i=1;i<=n;i++)f[i]=0.0; memset(tf,false,sizeof(tf)); memset(q,0,sizeof(q)); int head=1,tail=2; q[head]=1;tf[1]=true;f[1]=1.0; while(head!=tail) { int x=q[head]; for(int i=first[x];i!=0;i=a[i].next) { int y=a[i].y; if(f[y]<f[x]*a[i].d) { f[y]=f[x]*a[i].d; if(tf[y]==false) { tf[y]=true; q[tail]=y; tail++;if(tail>n)tail=1; } } /* printf("%d->%d %.3lf %.3lf %.3lf\n",x,y,f[x],a[i].d,f[y]); system("pause");*/ } tf[x]=false; head++;if(head>n)head=1; } printf("%.6lf percent\n",f[n]*100); } return 0; }