您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息