POJ 2240

再次1Y了

前面出现过这类套汇的题目的,POJ 1860。思路一样的,先抽象图论模型,枚举起始点,,用Bellman Ford判断是否出现连乘积大于1的环。注意对Bellman算法的改进,relax函数变为乘积更大时松弛,还有s点的最短距离的初始值要设为1。

 

#include <iostream> #include <map> #include <algorithm> #include <cstring> #define F(i,a,b) for (int i=a;i<=b;i++) using namespace std; map<string, int> name; double d[32], mtx[32][32]; int N, M, ne; class edge { public: int s, t; double l; edge() {} edge(int a, int b, double c) { s=a, t=b, l=c; } } e[2000]; bool relax(int x) //xth edge { int s=e[x].s, t=e[x].t; double l=e[x].l; if (d[t]<d[s]*l) { d[t]=d[s]*l; return true; } return false; } bool bellman(int s) { fill(d, d+N+1, -1); d[s]=1; bool refresh=true; for (int i=1;i<=N-1 && refresh;i++) { refresh=false; F(j,1,ne) { refresh=relax(j)||refresh; } } F(i,1,N) { if (d[i]*mtx[i][s]>1.0) return true; } return false; } int main() { // freopen ("in.txt", "r", stdin); int T=0; while (cin >> N && N!=0) { T++; string str1, str2; double t; F(i,1,N) { cin >> str1; name.insert( make_pair(str1, i) ); } memset( mtx, 0, sizeof(mtx) ); cin >> ne; F(i,1,ne) { cin >> str1 >> t >> str2; e[i]=edge( name[str1], name[str2], t); mtx[ name[str1] ][ name[str2] ]=t; } bool yes=false; cout << "Case " << T << ": "; F(i,1,N) { if ( bellman(i) ) { yes=true; cout << "Yes/n"; break; } } if (!yes) cout << "No/n"; } return 0; }

你可能感兴趣的:(c,算法,String,BI,pair)