HDU1217:Arbitrage(SPFA)
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1217
题目大意
在每种钱币间进行各种交换,最后换回自己如果能赚,那么就Yes,否则No
注意应为有负权所以dijsktra在这里行不通了可以用国产的spfa算法,可比bfs。
我的AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
using namespace std;
map<string,int> mat;
int n,m;
char str[100],s1[100],s2[100];
double trip[30][30],dis[30];
int main(void)
{
    int spfa(int src);
    int i,j,ans=1;
    double w;
    while(scanf("%d",&n)==1&&n)
    {
        mat.clear();
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if(i==j)
                trip[i][j]=1;
                else
                trip[i][j]=0;
            }
        }
        for(i=1;i<=n;i++)
        {
            scanf("%s",str);
            mat[str]=i;
        }
        scanf("%d",&m);
        while(m--)
        {
            scanf("%s%lf%s",s1,&w,s2);
            trip[mat[s1]][mat[s2]]=w;
        }
        int flag=0;
        for(i=1;i<=n;i++)
        {
            if(spfa(i))
            {
                flag=1;
                break;
            }
        }
        printf("Case %d: %s\n",ans++,flag?"Yes":"No");
    }
    return 0;
}
int spfa(int src)
{
    queue<int> q;
    int vis[30],i;
    memset(vis,0,sizeof(vis));
    memset(dis,0,sizeof(dis));//全为0,表示碰到有路就搜。
    dis[src]=1;
    vis[src]=1;
    q.push(src);
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        vis[now]=0;
        for(i=1;i<=n;i++)
        {
            if(dis[now]*trip[now][i]>dis[i])//有路就搜全部遍历。
            {
                dis[i]=dis[now]*trip[now][i];
                if(dis[src]>1)
                return 1;
                if(!vis[i])
                {
                    vis[i]=1;
                    q.push(i);
                }
            }
        }
    }
    return 0;
}
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号