Arbitrage 【HDU - 1217】【SPFA最短路】
阿新 • • 發佈:2019-01-06
題目連結
關於SPFA是一道很不錯的題,也有人用弗洛伊德去寫的,然而……我一開始就是用Dijkstra去某名奇妙的WA了一發…… 然後沒有任何想法!不知道WA在哪了,後來,一想,原來是其中可能存在無限迴圈的自環,因為他們可能存在相當於負環,而這道題的Yes的條件,就是必須得存在這樣的負環,所以,我們有可能得走幾遍這樣的負環,得到最後的答案。
#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 #define INF 0x3f3f3f3f #define efs 1e-7 using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxN = 35; int N, M, cnt, head[maxN], num[maxN]; bool inque[maxN]; double dis[maxN]; string money, m1, m2; map<string, int> mp; struct Eddge { int nex, to; double val; Eddge(int a=0, int b=0, double c=0):nex(a), to(b), val(c) {} }edge[maxN*maxN]; inline void addEddge(int u, int v, double val) { edge[cnt] = Eddge(head[u], v, val); head[u] = cnt++; } bool Spfa(int pos) { memset(dis, 0, sizeof(dis)); dis[pos] = 1.; queue<int> Q; Q.push(pos); num[pos]++; inque[pos] = true; while(!Q.empty()) { int u = Q.front(); Q.pop(); inque[u] = false; for(int i=head[u]; i!=-1; i=edge[i].nex) { int v = edge[i].to; double cost = edge[i].val; if(v == pos && dis[u] * cost > 1.) return true; if(dis[v] < dis[u] * cost && num[v] <= N) { dis[v] = dis[u] * cost; num[v]++; if(!inque[v]) { Q.push(v); inque[v] = true; } } } } return false; } inline void init() { cnt = 0; memset(head, -1, sizeof(head)); memset(num, 0, sizeof(num)); memset(inque, false, sizeof(inque)); } int main() { int Cas = 0; while(scanf("%d", &N) && N) { init(); for(int i=1; i<=N; i++) { cin>>money; mp[money] = i; } scanf("%d", &M); while(M--) { double val; cin>>m1>>val>>m2; addEddge(mp[m1], mp[m2], val); } printf("Case %d: ", ++Cas); printf("%s\n", Spfa(1)?"Yes":"No"); } return 0; }