zoukankan      html  css  js  c++  java
  • POJ 3259 Wormholes(SPFA算法)

    题意:

             有N块地,M条无向路,W条有向路,无向路的权值为正,有向路的权值为负,问自否存在负环。

     

    思路:

             用邻接表保存图,使用SPFA+SLF优化。

       判断是否存在负环时,另设一个数组用来记录从源点到各个点的最短路径所经过的路径条数,若路径条数大于等于N(点的个数),说明存在负环。(仔细想想为什么)

     

    AC代码,16ms…

     1 #include <cstdio>
     2 #include <string.h>
     3 #include <deque>
     4 using namespace std;
     5 const int N = 510, M = 5500, INF = 0x3f3f3f3f;
     6 int u[M], v[M], weigth[M], Next[M], first[N], D[N];
     7 bool SPFA(int n)
     8 {
     9     int t, num[N] = {0};
    10     bool cnt[N] = {0};
    11     memset(D, INF, sizeof(D));
    12     D[0] = 0;
    13     cnt[0] = true;
    14     deque<int> dq;
    15     dq.push_front(0);
    16     while(!dq.empty())
    17     {
    18         t = dq.front();
    19         dq.pop_front();
    20         for(int x=first[t]; ~x; x=Next[x])
    21         {
    22             if(D[v[x]] > D[u[x]] + weigth[x])
    23             {
    24                 D[v[x]] = D[u[x]] + weigth[x];
    25                 num[v[x]] = num[u[x]] + 1;
    26                 if(num[v[x]] >= n)
    27                     return false;
    28                 if(!cnt[v[x]])
    29                 {
    30                     if(!dq.empty() && D[v[x]] < D[dq.front()])
    31                         dq.push_front(v[x]);
    32                     else
    33                         dq.push_back(v[x]);
    34                     cnt[v[x]] = true;
    35                 }
    36             }
    37         }
    38         cnt[t] = false;
    39     }
    40     return true;
    41 }
    42 int main(void)
    43 {
    44     int kase, n, m, w, num;
    45     scanf("%d", &kase);
    46     while(kase--)
    47     {
    48         memset(first, -1, sizeof(first));
    49         scanf("%d %d %d", &n, &m, &w);
    50         num = 0;
    51         for(int i=0; i<m; ++i)
    52         {
    53             scanf("%d %d %d", u+num, v+num, weigth+num);
    54             --u[num], --v[num];
    55             Next[num] = first[u[num]];
    56             first[u[num]] = num++;
    57             u[num] = v[num-1], v[num] = u[num-1], weigth[num] = weigth[num-1];
    58             Next[num] = first[u[num]];
    59             first[u[num]] = num++;
    60         }
    61         for(int i=0; i<w; ++i)
    62         {
    63             scanf("%d %d %d", u+num, v+num, weigth+num);
    64             --u[num], --v[num], weigth[num] = 0 - weigth[num];
    65             Next[num] = first[u[num]];
    66             first[u[num]] = num++;
    67         }
    68         printf("%s
    ", SPFA(n) ? "NO" : "YES");
    69     }
    70 }
  • 相关阅读:
    网络基础复习02
    网络基础复习01
    python 基础复习之数据库02
    python 基础复习之数据库01
    python 基础复习 13
    python基础复习 12
    python基础复习 11
    python基础复习10
    列表切片,内置方法
    文件操作基础流程
  • 原文地址:https://www.cnblogs.com/corvey/p/4780447.html
Copyright © 2011-2022 走看看