POJ 3259 判断负圈
2016-06-23 15:10
183 查看
题意
图中两种边,一种正权值双向边,一种负权值单向边问是否存在负圈
思路
简单模板题,SPFA如果有节点入队超过节点数次,则存在负圈实现
#include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <algorithm> using namespace std; const int maxn = 505; vector<pair<int,int> > g[maxn]; queue<int> q; int dist[maxn]; int inQ[maxn], nums[maxn]; int n,m; bool SPFA(int s){ memset(inQ,0,sizeof(inQ)); memset(nums,0,sizeof(nums)); memset(dist,0x3f,sizeof(dist)); while (q.size()) q.pop(); dist[s] = 0; inQ[s] = 1; nums[s] = 1; q.push(s); while (q.size()){ int u = q.front(); inQ[u] = 0; q.pop(); for (int e = 0; e< g[u].size();e++){ int v = g[u][e].first; int w = g[u][e].second; if (dist[v] > dist[u] + w){ dist[v] = dist[u] + w; if (inQ[v] == 0){ q.push(v); inQ[v] = 1; nums[v]++; if (nums[v] > n){ return false; } } } } } return true; } int main(){ int w; int T; cin>>T; while (T--){ scanf("%d%d%d",&n,&m,&w); for (int i=0;i<n;i++){ g[i].clear(); } for (int i=0;i<m;i++){ int u,v,a; scanf("%d%d%d",&u,&v,&a); g[u-1].push_back({v-1,a}); g[v-1].push_back({u-1,a}); } for (int i=0;i<w;i++){ int u,v,a; scanf("%d%d%d",&u,&v,&a); g[u-1].push_back({v-1,-a}); } if (SPFA(0)){ puts("NO"); }else{ puts("YES"); } } return 0; }
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#递归算法之分而治之策略
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- C#算法之大牛生小牛的问题高效解决方法
- C#算法函数:获取一个字符串中的最大长度的数字
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- 经典排序算法之冒泡排序(Bubble sort)代码
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法