poj 2240 Arbitrage(bellman-ford spfa 判断正环)

http://poj.org/problem?id=2240

 

基本和poj 1860相同 只是把单点变成了任意点 做完1860再做这题就完全把思路套上就过了 

做完才发现网上的题解都用的是floyd 不过整体思路都是大同小异吧

不过在效率上好像就低下了太多(发现原来是cin的原因 真的是深深感到cin的恶意了)= =

 

bellman

#include<cstdio>

#include<cstring>

#include<cmath>

#include<queue>

#include<stack>

#include<iostream>

#include<algorithm>

using namespace std;

char str[50][50];

double u[1000],v[1000],w[1000];

double d[100];

int n,m;

int find(char*s)

{

   for(int i=1;i<=n;i++)

   {

       if(strcmp(s,str[i])==0)

        return i;

   }

}

int main()

{

    int i,j,k;

    int casee=1;

    char l[50],r[50];

    while(scanf("%d",&n)!=EOF)

    {

        if(n==0) break;

        for(i=1;i<=n;i++)

          scanf("%s",str[i]);

        scanf("%d",&m);

        for(i=1;i<=m;i++)

        {

            scanf("%s%lf%s",l,&w[i],r);

            u[i]=find(l);

            v[i]=find(r);

        }

        memset(d,0,sizeof(d));

        d[1]=20;

        int ok=0;

        for(k=0;k<n;k++)

        {

            for(i=1;i<=m;i++)

            {

                int x=u[i],y=v[i];

                if(d[x]*w[i]>d[y])

                {

                    d[y]=d[x]*w[i];

                }

            }

        }

        for(i=1;i<=m;i++)

        {

                if(ok) break;

                int x=u[i],y=v[i];

                if(d[x]*w[i]>d[y])

                {

                    ok=1;

                }

        }

        if(ok)

            printf("Case %d: Yes\n",casee++);

        else

            printf("Case %d: No\n",casee++);

       

    }

}
View Code

 

spfa

#include<cstdio>

#include<cstring>

#include<cmath>

#include<queue>

#include<stack>

#include<iostream>

#include<algorithm>

using namespace std;

char str[50][50];

int u[1000],v[1000];

int coun[1000];

double w[1000];

int first[1000],next[1000];

double d[100];

int n,m;

int find(char*s)

{

   for(int i=1;i<=n;i++)

   {

       if(strcmp(s,str[i])==0)

        return i;

   }

}

int main()

{

    int i,j,k;

    int casee=1;

    char l[50],r[50];

    while(scanf("%d",&n)!=EOF)

    {

        if(n==0) break;

        for(i=1;i<=n;i++)

          scanf("%s",str[i]);

        scanf("%d",&m);

        for(i=1;i<=n;i++) first[i]=-1;

        for(i=1;i<=m;i++)

        {

            scanf("%s%lf%s",l,&w[i],r);

            u[i]=find(l);

            v[i]=find(r);

            next[i]=first[u[i]];

            first[u[i]]=i;

        }

        memset(d,0,sizeof(d));

        memset(coun,0,sizeof(coun));

        d[1]=20;

        coun[1]++;

        int ok=0;

        int tot=0;

        int q[1000];

        bool inq[1000];

        memset(inq,0,sizeof(inq));

        q[tot++]=1;

        while(tot)

        {

            if(ok) break;

            int x=q[--tot];

            inq[x]=false;

            for(int e=first[x];e!=-1;e=next[e])

            {

                if(d[x]*w[e]>d[v[e]])

                {

                    d[v[e]]=d[x]*w[e];

                    if(!inq[v[e]])

                    {

                        inq[v[e]]=true;

                        q[tot++]=v[e];

                        coun[v[e]]++;

                        if(coun[v[e]]>n) {ok=1;break;}

                    }

                }

            }

        }

        if(ok)

            printf("Case %d: Yes\n",casee++);

        else

            printf("Case %d: No\n",casee++);



    }

}
View Code

 

你可能感兴趣的:(SPFA)