zoukankan      html  css  js  c++  java
  • 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
    ", graph.spfaNegRing(1) ? "YES" : "NO");
    97     }
    98     return 0;
    99 }
  • 相关阅读:
    [算法] 堆栈
    [刷题] PTA 02-线性结构3 Reversing Linked List
    java IO流 (八) RandomAccessFile的使用
    java IO流 (七) 对象流的使用
    java IO流 (六) 其它的流的使用
    java IO流 (五) 转换流的使用 以及编码集
    java IO流 (四) 缓冲流的使用
    java IO流 (三) 节点流(或文件流)
    java IO流 (二) IO流概述
    java IO流 (一) File类的使用
  • 原文地址:https://www.cnblogs.com/DarkScoCu/p/10527359.html
Copyright © 2011-2022 走看看