链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1217
题目:
3 USDollar BritishPound FrenchFranc 3 USDollar 0.5 BritishPound BritishPound 10.0 FrenchFranc FrenchFranc 0.21 USDollar 3 USDollar BritishPound FrenchFranc 6 USDollar 0.5 BritishPound USDollar 4.9 FrenchFranc BritishPound 10.0 FrenchFranc BritishPound 1.99 USDollar FrenchFranc 0.09 BritishPound FrenchFranc 0.19 USDollar 0
Case 1: Yes Case 2: No
分析与总结:
根据题意可知,只要找到正环便可判断为Yes,因此可以SPFA判环,或者建好邻接矩阵图用Floyd算法计算后,判断是否有d[i][i]>1即可。
1.Floyd
#include<cstdio> #include<iostream> #include<cstring> #include<queue> #include<map> #include<string> using namespace std; typedef double Type; const int INF = 0x7ffffff; const int VN = 35; const int EN = VN*VN; map<string, int>mp; int n,size,cnt; int head[VN]; Type d[VN][VN]; void init(){ size=0; cnt=0; mp.clear(); for(int i=1; i<=n; ++i){ d[i][i] = 1; for(int j=i+1; j<=n; ++j) d[i][j] = d[j][i] = 0; } } void Floyd(){ for(int k=1; k<=n; ++k) for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j){ d[i][j] = max(d[i][j], d[i][k]*d[k][j]); } } int main(){ char str1[50], str2[50]; int cas=1,m,u,v; double w; while(scanf("%d",&n)&&n){ init(); for(int i=0; i<n; ++i){ scanf("%s",str1); mp[str1] = ++cnt; } scanf("%d",&m); for(int i=0; i<m; ++i){ scanf("%s %lf %s",str1,&w,str2); u = mp[str1], v = mp[str2]; d[u][v] = w; } bool flag=false; Floyd(); for(int i=1; i<=n; ++i) if(d[i][i]>1.0) {flag=true; break;} printf("Case %d: ",cas++); if(flag) puts("Yes"); else puts("No"); } return 0; }
2.SPFA判正环
#include<cstdio> #include<iostream> #include<cstring> #include<string> #include<queue> #include<map> using namespace std; typedef double Type; const int INF = 0x7ffffff; const int VN = 35; const int EN = VN*VN; map<string, int>mp; int n,size,cnt; int head[VN]; bool inq[VN]; int counter[VN]; Type d[VN]; struct Edge{int v,next; Type w;}E[EN]; void addEdge(int u,int v,Type w){ E[size].v=v, E[size].w=w; E[size].next = head[u]; head[u] = size++; } void init(){ size=0; cnt=0; memset(head, -1, sizeof(head)); mp.clear(); } bool SPFA(int src){ memset(counter, 0, sizeof(counter)); memset(inq, 0, sizeof(inq)); for(int i=1; i<=n; ++i) d[i]=0; d[src] = 1; queue<int>q; q.push(src); while(!q.empty()){ int u = q.front(); q.pop(); inq[u] = false; for(int e=head[u]; e!=-1; e=E[e].next){ Type tmp = d[u]*E[e].w; // if(d[E[e].v] > tmp){ if(d[E[e].v]<tmp){ d[E[e].v] = tmp; if(!inq[E[e].v]){ inq[E[e].v] = true; q.push(E[e].v); if(++counter[E[e].v]>=n){ return true; } } } } } return false; } int main(){ char str1[50], str2[50]; int cas=1,m,u,v; double w; while(scanf("%d",&n)&&n){ init(); for(int i=0; i<n; ++i){ scanf("%s",str1); mp[str1] = ++cnt; } scanf("%d",&m); for(int i=0; i<m; ++i){ scanf("%s %lf %s",str1,&w,str2); u = mp[str1], v = mp[str2]; addEdge(u,v,w); } bool flag=false; for(int i=1; i<=n; ++i){ if(SPFA(i)){ flag=true; break; } } printf("Case %d: ",cas++); if(flag) puts("Yes"); else puts("No"); } return 0; }
—— 生命的意义,在于赋予它意义。
原创 http://blog.csdn.net/shuangde800 , By D_Double (转载请标明)