ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

POJ3259 Wormholes 【spfa判负环】

2019-09-07 11:00:25  阅读:281  来源: 互联网

标签:cnt num POJ3259 int vis 判负 spfa edge dis


题目链接:http://poj.org/problem?id=3259

Wormholes
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions:75598   Accepted: 28136

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..NM (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: A single integer, FF farm descriptions follow. 
Line 1 of each farm: Three space-separated integers respectively: NM, and W 
Lines 2..M+1 of each farm: Three space-separated numbers (SET) 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 (SET) that describe, respectively: A one way path from S to E that also moves the traveler back T seconds. 题目大意:n 个点, m 条双向边,代表经过所需的时间,w 条单向边,代表经过所减少的时间。问该图中是否存在负环。 思路: 1.简单的判环,用spfa即可,在不存在环的情况下,任意点在进行路径松弛时,最多被其他的点更新一次。那么任意点的最多入队次数只能是 n 次。当存在任何一点的入队次数大于顶点数n,即说明存在环。 2.判负环,即路径往小松弛。判正环时,即路径往大更新。注意dis数组初始化即可。 代码如下:
 1 #include<stdio.h>
 2 #include<queue>
 3 #include<string.h>
 4 #define mem(a, b) memset(a, b, sizeof(a))
 5 const int MAXN = 550;
 6 const int MAXM = 3000;
 7 const int inf = 0x3f3f3f3f;
 8 using namespace std;
 9 
10 int n, m, k; //n个点 m条双向边 k个虫洞(单向边) 
11 int head[MAXN], cnt;
12 int vis[MAXN], num[MAXN];//num表示第i个点的入队次数 用来判断负环是否存在 
13 int dis[MAXN], flag;
14 queue<int> Q;
15 
16 struct Edge
17 {
18     int to, next, w;
19 }edge[2 * MAXM];
20 
21 void add(int a, int b, int c)
22 {
23     cnt ++;
24     edge[cnt].to = b;
25     edge[cnt].w = c;
26     edge[cnt].next = head[a];
27     head[a] = cnt;
28 }
29 
30 void spfa(int st)
31 {
32     while(!Q.empty())    Q.pop();
33     mem(vis, 0), mem(dis, inf), mem(num, 0);
34     Q.push(st);
35     vis[st] = 1;
36     num[st] = 1;
37     dis[st] = 0;
38     while(!Q.empty())
39     {
40         int a = Q.front();
41         Q.pop();
42         vis[a] = 0;
43         for(int i = head[a]; i != -1; i = edge[i].next)
44         {
45             int to = edge[i].to;
46             if(dis[to] > dis[a] + edge[i].w)
47             {
48                 dis[to] = dis[a] + edge[i].w;
49                 if(!vis[to])
50                 {
51                     vis[to] = 1;
52                     Q.push(to);
53                     num[to] ++;
54                     if(num[to] > n)
55                     {
56                         flag = 1;
57                         break;
58                     }
59                 }
60             }
61         }
62         if(flag)
63             break;
64     }
65     if(flag)
66         printf("YES\n");
67     else
68         printf("NO\n");
69 }
70 
71 int main()
72 {
73     int T;
74     scanf("%d", &T);
75     while(T --)
76     {
77         cnt = 0, flag = 0, mem(head, -1);
78         scanf("%d%d%d", &n, &m, &k);
79         for(int i = 1; i <= m; i ++)
80         {
81             int a, b, c;
82             scanf("%d%d%d", &a, &b, &c);
83             add(a, b, c);
84             add(b, a, c);
85         }
86         for(int i = 1; i <= k; i ++)
87         {
88             int a, b, c;
89             scanf("%d%d%d", &a, &b, &c);
90             add(a, b, -c);
91         }
92         spfa(1);
93     }
94     return 0;
95 }
POJ3259

 

 

标签:cnt,num,POJ3259,int,vis,判负,spfa,edge,dis
来源: https://www.cnblogs.com/yuanweidao/p/11479589.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有