Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 33948 | Accepted: 12376 |
Description
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, M (1 ≤ M ≤ 2500) paths, and W (1 ≤ W ≤ 200) wormholes.
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 (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 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
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 8
Sample Output
NO YES 注:主要用spfa判断负圈的存在,测试数据有点水,因为各点并非是全连通的,此时可以通过由0点向每个点加一条权值为0的边。 source code: //双端队列实现的SLF优化的spfa#include <cstdio> #include <cstring> #include <deque> using namespace std; const int inf = 30000000; const int maxn = 505; const int maxm = 50000; int head[maxn], next[maxm], vis[maxn], dis[maxn], cnt[maxn]; int n, m, w, e; struct node{ int u, v, c; node(){} node(int u, int v, int c):u(u), v(v), c(c){} }p[maxm]; void addnode(int u, int v, int c) { p[e] = node(u, v, c); next[e] = head[u]; head[u] = e++; } bool relax(int u, int v, int c) { if (dis[v] > dis[u] + c) { dis[v] = dis[u] + c; return true; } return false; } void init() { e = 0; memset(head, -1, sizeof(head)); memset(next, -1, sizeof(next)); } bool spfa() { for (int i = 1; i <= n; i++) dis[i] = inf; memset(vis, 0, sizeof(vis)); memset(cnt, 0, sizeof(cnt)); dis[1] = 0; vis[1] = 1; deque<int> que; while (!que.empty()) que.pop_front(); que.push_back(1); while (!que.empty()) { int u = que.front(); que.pop_front(); vis[u] = 0; for (int i = head[u]; i + 1; i = next[i]) { if (relax(u, p[i].v, p[i].c) && !vis[p[i].v]) { if ((++cnt[p[i].v]) > n) return true; vis[p[i].v] = 1; if (!que.empty()) { if (dis[p[i].v] > dis[que.front()]) que.push_back(p[i].v); else que.push_front(p[i].v); } else que.push_back(p[i].v); } } } return false; } int main() { //freopen("F:\\test.txt", "r", stdin); int cas, u, v, c; scanf("%d", &cas); while (cas--) { init(); // for (int i = 1; i <= n; i++) { //通过由0点向每个点加一条边,权值为0 // addnode(0, i, 0); // //addnode(i, 0, 0); // } scanf("%d%d%d", &n, &m, &w); while (m--) { scanf("%d%d%d", &u, &v, &c); addnode(u, v, c); addnode(v, u, c); } while (w--) { scanf("%d%d%d", &u, &v, &c); addnode(u, v, -c); } if (spfa()) puts("YES"); else puts("NO"); } return 0; }