SPFA算法模板(刘汝佳版)--Wormholes POJ - 3259

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-26 10:35:26

一直觉得紫书代码比较精炼,就照着紫书上不完整的SPFA算法写了一道判断是否有负权边的题,题目链接:https://vjudge.net/problem/POJ-3259,细节看代码

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cmath>
 5 #include<iostream>
 6 #include<vector>
 7 #include<set>
 8 #include<queue>
 9 #define MAXN 500100
10 #define INF 0x3f3f3f3f
11 using namespace std;
12 typedef long long ll;
13 int n,m,w;
14 struct node
15 {
16     int from,to,cost;
17     node(int a,int b,int c):from(a),to(b),cost(c){}
18 };///边的结构体
19 vector<int>G[MAXN];///G[i]中的元素代表以i为起点的边
20 vector<node>edges;///存放所有的边
21 bool inq[MAXN];
22 int d[MAXN],cnt[MAXN];
23 bool SPFA(int s)
24 {
25 
26     for(int i=0;i<=n;i++)d[i]=INF;
27     memset(inq,0,sizeof(inq));
28      memset(cnt,0,sizeof(cnt));///初始化
29     d[s]=0;
30     inq[s]=true;
31     queue<int> q;
32     q.push(s);
33     while(!q.empty())
34     {
35         int u=q.front();q.pop();
36         inq[u]=false;
37         for(int i=0;i<G[u].size();i++)///对以队首为起点的边进行松弛
38         {
39             node& e=edges[G[u][i]];
40             if(d[u]<INF&&d[e.to]>d[u]+e.cost)
41             {
42                 d[e.to]=d[u]+e.cost;
43                 if(!inq[e.to])///每松弛一个点加入队列
44                 {
45                     q.push(e.to);
46                     inq[e.to]=true;
47                     if(++cnt[e.to]>n)return false;///如果一个点被松弛n次以上说明有负环
48                 }
49             }
50         }
51     }
52     return true;
53 }
54 void AddEdge(int from,int to,int dist)
55     {
56         edges.push_back(node(from,to,dist));
57         int k = edges.size();
58         G[from].push_back(k-1);///初始化边,将他们编号
59     }
60 int main()
61 {
62     int t;
63     scanf("%d",&t);
64     while(t--)
65     {
66         scanf("%d%d%d",&n,&m,&w);
67         for(int i=1;i<MAXN;i++)G[i].clear();
68         edges.clear();
69         for(int i=0;i<m;i++)
70         {
71             int u,v,cost;
72             scanf("%d%d%d",&u,&v,&cost);
73             AddEdge(u,v,cost);AddEdge(v,u,cost);///这里路径是双向的(我这里被卡很久)
74         }
75         for(int i=0;i<w;i++)
76         {
77             int u,v,cost;
78             scanf("%d%d%d",&u,&v,&cost);
79             AddEdge(u,v,-cost);///虫洞权值为负,且为单向
80         }
81         if(!SPFA(1))printf("YES\n");
82         else printf("NO\n");
83     }
84     return 0;
85 }

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!