• POJ-3259 Wormholes---SPFA判断有无负环


    题目链接:

    https://vjudge.net/problem/POJ-3259

    题目大意:

    农夫约翰在探索他的许多农场,发现了一些惊人的虫洞。虫洞是很奇特的,因为它是一个单向通道,可让你进入虫洞的前达到目的地!他的N(1≤N≤500)个农场被编号为1..N,之间有M(1≤M≤2500)条路径,W(1≤W≤200)个虫洞。FJ作为一个狂热的时间旅行的爱好者,他要做到以下几点:开始在一个区域,通过一些路径和虫洞旅行,他要回到最开时出发的那个区域出发前的时间。也许他就能遇到自己了:)。为了帮助FJ找出这是否是可以或不可以,他会为你提供F个农场的完整的映射到(1≤F≤5)。所有的路径所花时间都不大于10000秒,所有的虫洞都不大于万秒的时间回溯。

    思路:

    注意一开始给的通道为正常通道,是双向通道,后来给的通道是单向通道虫洞,建出图后用SPFA判断有无负环即可

    也可以用Floyd

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #include<stack>
     8 #include<map>
     9 #include<set>
    10 #include<sstream>
    11 using namespace std;
    12 typedef long long ll;
    13 const int maxn = 500 + 10;
    14 const int INF = 0x3f3f3f3f;
    15 int T, n, m, cases, tot;
    16 struct edge
    17 {
    18     int u, v, w;
    19     edge(int u, int v, int w):u(u), v(v), w(w){}
    20 };
    21 vector<edge>e;
    22 vector<int>G[maxn];
    23 void init()
    24 {
    25     for(int i = 0; i <= n; i++)G[i].clear();
    26     e.clear();
    27 }
    28 void addedge(int u, int v, int w)
    29 {
    30     e.push_back(edge(u, v, w));
    31     tot = e.size();
    32     G[u].push_back(tot - 1);
    33 }
    34 bool vis[maxn];
    35 int cnt[maxn], d[maxn];
    36 bool bellman(int u)
    37 {
    38     queue<int>q;
    39     memset(vis, 0, sizeof(vis));
    40     memset(cnt, 0, sizeof(cnt));
    41     for(int i = 0; i <= n; i++)d[i] = INF;
    42     d[u] = 0;
    43     vis[u] = 1;
    44     q.push(u);
    45     while(!q.empty())
    46     {
    47         int u = q.front();
    48         q.pop();
    49         vis[u] = 0;//取出队列
    50         for(int i = 0; i < G[u].size(); i++)
    51         {
    52             int v = e[G[u][i]].v;
    53             int w = e[G[u][i]].w;
    54             if(d[u] < INF && d[v] > d[u] + w)
    55             {
    56                 d[v] = d[u] + w;
    57                 if(!vis[v])
    58                 {
    59                     q.push(v);//松弛成功,加入队列
    60                     vis[v] = 1;//添加入队标记
    61                     if(++cnt[v] >= n)return true;//存在负环
    62                 }
    63             }
    64         }
    65     }
    66     return false;
    67 }
    68 int main()
    69 {
    70     cin >> T;
    71     int w, x, y, z;
    72     while(T--)
    73     {
    74         cin >> n >> m >> w;
    75         init();
    76         for(int i = 0; i < m; i++)
    77         {
    78             scanf("%d%d%d", &x, &y, &z);
    79             addedge(x, y, z);
    80             addedge(y, x, z);
    81         }
    82         for(int i = 0; i < w; i++)
    83         {
    84             scanf("%d%d%d", &x, &y, &z);
    85             addedge(x, y, -z);
    86         }
    87         if(bellman(1))cout<<"YES"<<endl;
    88         else cout<<"NO"<<endl;
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    namenode无法自动切换的问题
    HDFS 安全模式的理解
    程序启动-Runloop
    浅谈MVC和MVVM模式
    Runtime 运行时之一:消息转发
    Runtime 运行时之一:消息传递
    Runtime 运行时之一:类与对象
    GCC 编译详解
    UIView中的坐标转换
    Xcode 利用VVDocumenter 生成注释 通过设置 再生成注释文档
  • 原文地址:https://www.cnblogs.com/fzl194/p/8732994.html
Copyright © 2020-2023  润新知