P3385 模板负环

Posted wstong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3385 模板负环相关的知识,希望对你有一定的参考价值。

P3385 【模板】负环

Bellman-Ford

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 2005, maxm = 3005;
 4 const int inf = 0x3f3f3f3f;
 5 struct edge {
 6     int v, w;
 7 };
 8 vector<edge> maps[maxn];
 9 int dis[maxn], n, m;
10 
11 bool BellmanFord(int s) {  // s为源点
12     fill(dis+1, dis+1+n, inf);
13     dis[s] = 0;
14     for (int i = 1; i <= n-1; i++) {
15         for (int u = 1; u <= n; u++) {
16             for (int j = 0; j < maps[u].size(); j++) {
17                 int v = maps[u][j].v;
18                 int w = maps[u][j].w;
19                 if (dis[u] + w < dis[v]) {
20                     dis[v] = dis[u] + w;
21                 }
22             }
23         }
24     }
25     
26     if (maps[s].size() == 0) return true;  // 如果s点没有和其他点相连,则没有负环 
27     for (int u = 1; u <= n; u++) {
28         for (int j = 0; j < maps[u].size(); j++) {
29             int v = maps[u][j].v;
30             int w = maps[u][j].w;
31             if (dis[u] + w < dis[v])
32                 return false;
33         }
34     }
35     return true;
36 }
37 int main() {
38     int t; scanf("%d",&t);
39     while (t--) {
40         scanf("%d%d",&n,&m);
41         for (int i = 1; i <= n; i++) maps[i].clear();
42 
43         for (int i = 1; i <= m; i++) {
44             int u, v, w; scanf("%d%d%d",&u,&v,&w);
45             if (w < 0) maps[u].push_back(edge{v,w});
46             else {
47                 maps[u].push_back(edge{v,w});
48                 maps[v].push_back(edge{u,w});
49             }
50         }
51         bool flag = BellmanFord(1);
52            if (flag) puts("N0");
53            else puts("YE5");
54     }
55 }

 

spfa

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 2005;
 4 struct edge {
 5     int v, w;
 6 };
 7 vector<edge> maps[maxn];
 8 int dis[maxn], tim[maxn], n, m;
 9 bool vis[maxn];
10 
11 void add(int u, int v, int w) {
12     maps[u].push_back(edge{v,w});
13 }
14 bool spfa(int s) {
15     memset(dis, 0x3f3f3f3f, sizeof(dis));
16     memset(tim,0,sizeof(tim));
17     memset(vis,0,sizeof(vis));
18     queue<int> que;
19     que.push(s), dis[s] = 0, tim[s]++, vis[s] = true;
20     while(!que.empty()) {
21         int u = que.front();
22         if (tim[u] > n) return false;  // 出现负环
23         que.pop();
24         vis[u] = false;
25         for(int i = 0; i < maps[u].size(); i++) {
26             int v = maps[u][i].v;
27             int w = maps[u][i].w;
28             if(dis[v] > dis[u]+w) {
29                 dis[v] = dis[u] + w;
30                 if(vis[v] == false) {
31                     que.push(v);
32                     vis[v] = true;
33                     tim[v]++;
34                 }
35             }
36         }
37     }
38     return true;  // 没有出现负环
39 }
40 int main() {
41     int t; scanf("%d",&t);
42     while(t--) {
43         scanf("%d%d",&n,&m);
44         for (int i = 1; i <= n; i++) maps[i].clear();
45         for(int i = 1; i <= m; i++) {
46             int u, v, w; scanf("%d%d%d",&u,&v,&w);
47             if (w < 0) add(u,v,w);
48             else {
49                 add(u,v,w);
50                 add(v,u,w);
51             }
52         }
53         bool flag = spfa(1);
54         if (flag) puts("N0");
55            else puts("YE5");
56     }
57     return 0;
58 }

 

以上是关于P3385 模板负环的主要内容,如果未能解决你的问题,请参考以下文章

P3385 模板负环

P3385 模板负环

ybtoj 最短路径课堂过关 例题2luogu P3385SPFA(判负环)负环判断 & 模板负环

洛谷P3385 模板负环 DFS-SPFA 判负环 图论

P3385 模板负环

p3385 模板负环(spfa)