【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,否则概率越乘越大。

代码

#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;
}
我的代码

 

posted @ 2017-11-13 13:44  ZSYZlhy  阅读(203)  评论(0编辑  收藏  举报