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
",casee++);
        else
            printf("Case %d: No
",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
",casee++);
        else
            printf("Case %d: No
",casee++);

    }
}
View Code
原文地址:https://www.cnblogs.com/sola1994/p/4239916.html