最短路 - spfa
阿新 • • 發佈:2017-11-05
class {} res ont nal farmer orm sizeof size
, M (1 ≤ M ≤ 2500) paths, and W (1 ≤ W ≤ 200) wormholes.
(1 ≤ F ≤ 5) of his farms. No paths will take longer than 10,000 seconds to travel and no wormhole can bring FJ back in time by more than 10,000 seconds.
Input
Line 1: A single integer, F. F farm descriptions follow.
Line 1 of each farm: Three space-separated integers respectively: N, M, and W
Lines 2.. M+1 of each farm: Three space-separated numbers ( S, E, T) that describe, respectively: a bidirectional path between S and E that requires T seconds to traverse. Two fields might be connected by more than one path.
Lines M+2.. M+ W+1 of each farm: Three space-separated numbers ( S, E, T) that describe, respectively: A one way path from S to E that also moves the traveler back T seconds. Output Lines 1.. F: For each farm, output "YES" if FJ can achieve his goal, otherwise output "NO" (do not include the quotes). Sample Input
For farm 2, FJ could travel back in time by the cycle 1->2->3->1, arriving back at his starting location 1 second before he leaves. He could start from anywhere on the cycle to accomplish this. 題意 : 有一個新概念蟲洞,這個人可以穿過這條道路,並且時間會回溯T妙,問此人是否可以通過穿越蟲洞回溯時間看到自己。實質上就是判斷圖中有無負環。 思路 : SPFA : BF算法的優化,從一個點出發,更新它可以到達的所有點,把可以到的,更新的點,並且不再隊列中的點,再重新加入到隊列中。 如何判斷有無負環呢?一個點的更新次數如果大於 n-1次,那麽一定存在負環,因為一個點被加入隊列兩次,意味著這個點在BF 中被更新兩次,那麽這個點如果加入隊列的次數大於 n-1 次,那麽則存在負環。 代碼示例 :
While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination at a time that is BEFORE you entered the wormhole! Each of FJ‘s farms comprises N (1 ≤ N ≤ 500) fields conveniently numbered 1..N
As FJ is an avid time-traveling fan, he wants to do the following: start at some field, travel through some paths and wormholes, and return to the starting field a time before his initial departure. Perhaps he will be able to meet himself :) .
To help FJ find out whether this is possible or not, he will supply you with complete maps to F
Line 1 of each farm: Three space-separated integers respectively: N, M, and W
Lines 2.. M+1 of each farm: Three space-separated numbers ( S, E, T) that describe, respectively: a bidirectional path between S and E that requires T seconds to traverse. Two fields might be connected by more than one path.
Lines M+2.. M+ W+1 of each farm: Three space-separated numbers ( S, E, T) that describe, respectively: A one way path from S to E that also moves the traveler back T seconds. Output Lines 1.. F: For each farm, output "YES" if FJ can achieve his goal, otherwise output "NO" (do not include the quotes). Sample Input
2 3 3 1 1 2 2 1 3 4 2 3 1 3 1 3 3 2 1 1 2 3 2 3 4 3 1 8Sample Output
NO YESHint For farm 1, FJ cannot travel back in time.
For farm 2, FJ could travel back in time by the cycle 1->2->3->1, arriving back at his starting location 1 second before he leaves. He could start from anywhere on the cycle to accomplish this. 題意 : 有一個新概念蟲洞,這個人可以穿過這條道路,並且時間會回溯T妙,問此人是否可以通過穿越蟲洞回溯時間看到自己。實質上就是判斷圖中有無負環。 思路 : SPFA : BF算法的優化,從一個點出發,更新它可以到達的所有點,把可以到的,更新的點,並且不再隊列中的點,再重新加入到隊列中。 如何判斷有無負環呢?一個點的更新次數如果大於 n-1次,那麽一定存在負環,因為一個點被加入隊列兩次,意味著這個點在BF 中被更新兩次,那麽這個點如果加入隊列的次數大於 n-1 次,那麽則存在負環。 代碼示例 :
const int inf = 1 << 29; int n,m, w; struct ed { int to, cost; ed(int _t = 0, int _c = 0):to(_t),cost(_c){} }; vector<ed>edge[505]; bool vis[505]; int d[505]; int cnt[505]; bool spfa(){ queue<int>que; memset(cnt, 0, sizeof(cnt)); memset(vis, false, sizeof(vis)); for(int i = 1; i <= 500; i++) d[i] = inf; d[1] = 0; cnt[1] = 1; que.push(1); while(!que.empty()){ int u = que.front(); que.pop(); vis[u] = false; for(int i = 0; i < edge[u].size(); i++){ int to = edge[u][i].to; int cost = edge[u][i].cost; if (d[u]+cost < d[to]){ d[to] = d[u]+cost; if (!vis[to]){ vis[to] = true; que.push(to); cnt[to]++; if (cnt[to] > n) return true; } } } } return false; } int main() { int t; int a, b, c; cin >>t; while(t--){ scanf("%d%d%d", &n, &m, &w); for(int i = 1; i <= 500; i++) edge[i].clear(); for(int i = 1; i <= m; i++){ scanf("%d%d%d", &a, &b, &c); edge[a].push_back(ed(b,c)); edge[b].push_back(ed(a,c)); } for(int i = 1; i <= w; i++){ scanf("%d%d%d", &a, &b, &c); edge[a].push_back(ed(b, -c)); } if (spfa()) printf("YES\n"); else printf("NO\n"); } return 0; }
最短路 - spfa