昆虫洞

昆虫洞

 

Problem Description

当农场主John在开垦他的农场时,发现了许多奇怪的昆虫洞。这些昆虫洞是单向的,并且可以从入口到出口,并且使得时间倒退一段。John的每个农场包含N(1≤N≤500)块地,编号从1~N,这N快地之间有M(1≤M≤2500)条路、W(1≤W≤200)个昆虫洞。
因为John是一个狂热的时间旅行迷,他想尝试着做这样一件事:从某块地出发,通过一些路径和昆虫洞,返回出发点,并且时间早于出发时间,这样或许他可以遇到他自己。试帮助John判断是否可行。他将提供他的F(1≤F≤5)个农场的完整地图。每条路走完所需时间不超过10 000秒,每个昆虫洞倒退的事件也不超过10 000秒。

Input

输入文件第1行为一个整数F,表示F个测试数据,每个测试数据描绘了一个农场。接下来是F个农场的数据。
每个农场的第1行为3个整数:N、M和W。第2行至第M+1行,每行为3个整数:S、E和T,表示一条从S到E的双向路径,通过这条路径所需事件为T秒,两块地之间至多有一条路。第M+2~第M+W+1行,每行3个整数:S、E和T,表示从S到E的一条单向路,通过这条路使得时间倒退T秒。

Output

对每个测试数据,如果John能实现自己的目标,输出”YES”;否则输出”NO”。

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算法,百度一下,然后学一下这个算法,这个题相当于模板题。然后测试数据是,最后一组测试用例没有换行。是真滴gay.

  1 #include<bits/stdc++.h>
  2 
  3 using namespace std;
  4 const int N = 5210;
  5 const int INF = 0xFFFFFFF;
  6 
  7 struct edge{
  8   int v, w, next;
  9 }edges[N];
 10 
 11 int dist[N], num[N], frist[N];
 12 bool vis[N];
 13 int n, m, w;
 14 int e_sums; 
 15 
 16 int Scan() { //输入挂
 17   int res = 0, ch, flag = 0;
 18   if ((ch = getchar()) == '-')
 19     flag = 1;
 20   else if (ch >= '0' && ch <= '9')
 21     res = ch - '0';
 22   while ((ch = getchar()) >= '0' && ch <= '9')
 23     res = res * 10 + ch - '0';
 24   return flag ? -res : res;
 25 }
 26 
 27 void Out (int a) {    //输出挂
 28   if (a > 9)
 29     Out(a / 10);
 30   putchar(a % 10 + '0');
 31 }
 32 
 33 void addEdge (int u, int v, int w) {
 34   edges[e_sums].v = v;
 35   edges[e_sums].w = w;
 36   edges[e_sums].next = frist[u];
 37   frist[u] = e_sums++;
 38 }
 39 
 40 bool spfa() {
 41   queue<int> que;
 42   dist[1] = 0;
 43   vis[1] = true;
 44   que.push(1);
 45   num[1]++;
 46   while (que.size()) {
 47     int u = que.front();
 48     que.pop();
 49     vis[u] = false;
 50     for (int i = frist[u]; i != -1; i = edges[i].next) {
 51       int v = edges[i].v;
 52       if (dist[v] > dist[u] + edges[i].w) {
 53         dist[v] = dist[u] + edges[i].w;
 54         if ( !vis[v] ) {
 55           vis[v] = true;
 56           que.push(v);
 57           num[v]++;
 58           if (num[v] > n) {
 59             return true;
 60           }
 61         }
 62       }
 63     }
 64   }
 65   return false;
 66 }
 67 
 68 
 69 int main() {
 70   int t;
 71   //scanf("%d", &t);
 72   t = Scan();
 73   int gz = 1;
 74   while (t--) {
 75     if (!gz)putchar('\n');
 76     gz = 0;
 77     e_sums = 0;
 78     memset(frist, -1, sizeof(frist));
 79     memset(vis, false, sizeof(vis));
 80     memset(num, 0, sizeof(num));
 81 
 82     //scanf("%d %d %d", &n, &m, &w);
 83     n = Scan(), m = Scan(), w = Scan();
 84     for (int i = 1; i <= n; i++) {
 85       dist[i] = INF;
 86     }
 87    
 88 
 89     int x, y, z;
 90     for (int i = 0; i < m; i++) {
 91       //scanf("%d %d %d", &x, &y, &z);
 92       x = Scan(), y = Scan(), z = Scan();
 93       addEdge(x, y, z);
 94       addEdge(y, x, z);
 95     }
 96     
 97     for (int i = 0; i < w; i++) {
 98       //scanf("%d %d %d", &x, &y, &z);
 99       x = Scan(), y = Scan(), z = Scan();
100       addEdge(x, y, -z);
101     }
102 
103     if ( spfa() ) {
104       printf("YES");
105     } else {
106       printf("NO");
107     }
108   }
109   return 0;
110 }
View Code

感觉我同学,强行试出来,这个格式错误的解决办法,这才是真大佬。

posted @ 2019-07-18 16:24  龚政  阅读(347)  评论(0编辑  收藏  举报