poj 3259 Wormholes : spfa 双端队列优化 判负环 O(k*E)

 1 /**
 2 problem: http://poj.org/problem?id=3259
 3 spfa判负环:
 4 当有个点被松弛了n次,则这个点必定为负环中的一个点(n为点的个数)
 5 spfa双端队列优化:
 6 维护队列使其dist小的点优先处理
 7 **/
 8 #include<stdio.h>
 9 #include<deque>
10 #include<algorithm>
11 using namespace std;
12 
13 class Graphics{
14 const static int MAXN = 505;
15 const static int MAXM = 2505 * 2 + 205;
16 const static int INF = 0x7fffffff;
17 private:
18     struct Edge{
19         int to, dist, next;
20     }edge[MAXM];
21     int first[MAXN], sign, sumOfPoint;
22 public:
23     void init(int n){
24         sumOfPoint = n;
25         for(int i = 1; i <= n; i ++){
26             first[i] = -1;
27         }
28         sign = 0;
29     }
30     void addEdgeOneWay(int u, int v, int w){
31         edge[sign].dist = w;
32         edge[sign].to = v;
33         edge[sign].next = first[u];
34         first[u] = sign ++;
35     }
36     void addEdgeTwoWay(int u, int v, int w){
37         addEdgeOneWay(u, v, w);
38         addEdgeOneWay(v, u, w);
39     }
40     bool spfaNegRing(int start){
41         bool *vis = new bool[sumOfPoint+1];
42         int *dist = new int[sumOfPoint+1];
43         int *cnt = new int[sumOfPoint+1];
44         for(int i = 1; i <= sumOfPoint; i ++){
45             vis[i] = 0;
46             cnt[i] = 0;
47             dist[i] = INF;
48         }
49         deque<int> que;
50         que.push_front(start);
51         dist[start] = 0;
52         vis[start] = 1;
53         while(!que.empty()){
54             int now = que.front();
55             que.pop_front();
56             vis[now] = 0;
57             for(int i = first[now]; i != -1; i = edge[i].next){
58                 int to = edge[i].to, eDist = edge[i].dist;
59                 if(dist[now] + eDist < dist[to]){
60                     dist[to] = dist[now] + eDist;
61                     cnt[to] ++;
62                     if(cnt[to] >= sumOfPoint) { /// 如果这个点已经松弛n次则它必定是负环中的一个点
63                         delete []vis; delete []dist; return true;
64                     }
65                     if(!vis[to]){
66                         vis[to] = 1;
67                         if(que.empty() || dist[to] <= dist[que.front()])
68                             que.push_front(to);
69                         else
70                             que.push_back(to);
71                     }
72                 }
73             }
74         }
75         delete []vis; delete []dist; return false;
76     }
77 }graph;
78 
79 int main(){
80     int f;
81     scanf("%d", &f);
82     while(f --){
83         int n, m, w;
84         scanf("%d%d%d", &n, &m, &w);
85         graph.init(n);
86         while(m --){
87             int s, e, t;
88             scanf("%d%d%d", &s, &e, &t);
89             graph.addEdgeTwoWay(s, e, t);
90         }
91         while(w --){
92             int s, e, t;
93             scanf("%d%d%d", &s, &e, &t);
94             graph.addEdgeOneWay(s, e, -t);
95         }
96         printf("%s\n", graph.spfaNegRing(1) ? "YES" : "NO");
97     }
98     return 0;
99 }

 

posted @ 2019-03-13 23:02  DarkScoCu  阅读(243)  评论(0编辑  收藏  举报