标签:amp clu rom sep nes change 路径 each pen
Input
Output
Sample Input
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
Sample Output
Case 1: Yes Case 2: No
给你一个汇率表,找出其中有没有一种能创造无限金钱的环?这是我第一次写的比较清醒的spfa。
spfa判环有两种:
1.dfs:判断某个点是否在同一条路径出现多次
2.bfs:判断某个点入队的次数是否大于自身的入度
代码如下:
1 #include <iostream> 2 #include <queue> 3 #include <cstdio> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <map> 8 #include <vector> 9 using namespace std; 10 #define M 9000 11 map <string,int> money;//将货币映射成数字 12 struct Edge 13 { 14 int u,v; 15 double rate; 16 }edge[M]; 17 vector <int> g[50];//存图 18 bool inque[50];//标记是否入队 19 double price[50];//到达某点的最大汇率(类似距离) 20 int cnt[50];//标记点的入队次数 21 int in_degree[50];//入度 22 int toNum (string x) 23 { 24 return money[x]; 25 } 26 int n,m; 27 void init() 28 { 29 for (int i=0;i<50;++i){ 30 inque[i]=false; 31 price[i]=0; 32 cnt[i]=0; 33 } 34 } 35 bool spfa(int x) 36 { 37 queue<int>q; 38 cnt[x]++; 39 price[x]=1.0; 40 inque[x]=true; 41 q.push(x); 42 while (!q.empty()){ 43 int now=q.front(); 44 q.pop(); 45 inque[now]=false; 46 for (int i=0;i<g[now].size();++i){ 47 int e=g[now][i]; 48 int nxt=edge[e].v; 49 if (price[nxt]<price[now]*edge[e].rate){ 50 price[nxt]=price[now]*edge[e].rate;//松弛 51 if (!inque[nxt]){ 52 inque[nxt]=true; 53 q.push(nxt); 54 if (++cnt[nxt]>in_degree[nxt]){//某点的入队次数大于它的入度 55 return true; 56 } 57 } 58 } 59 } 60 } 61 return false; 62 } 63 int main() 64 { 65 //freopen("de.txt","r",stdin); 66 int casee=0; 67 while (~scanf("%d",&n)){ 68 if (n==0) break; 69 money.clear(); 70 for(int i=0;i<50;++i) 71 g[i].clear(); 72 for (int i=0;i<50;++i) 73 in_degree[i]=0; 74 for (int i=0;i<n;++i){ 75 string mny; 76 cin>>mny; 77 money[mny]=i; 78 } 79 scanf("%d",&m); 80 for (int i=0;i<m;++i){ 81 string a,b; 82 double x; 83 cin>>a>>x>>b; 84 edge[i].u=toNum(a); 85 edge[i].v=toNum(b); 86 edge[i].rate=x; 87 g[edge[i].u].push_back(i); 88 in_degree[edge[i].v]++; 89 } 90 bool ok=false; 91 for (int i=0;i<n;++i){//从每个点跑spfa 92 init();//记得每次初始化 93 if (spfa(i)){ 94 ok=true; 95 break; 96 } 97 } 98 if (ok) 99 printf("Case %d: Yes\n",++casee); 100 else 101 printf("Case %d: No\n",++casee); 102 } 103 return 0; 104 }
这题813ms过的...folyd好像只要几十ms,就当练习spfa了。
标签:amp clu rom sep nes change 路径 each pen
原文地址:http://www.cnblogs.com/agenthtb/p/6348079.html