对应模板题POJ3259
题意是判断是否存在负环
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#define MAXN 500100
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int n,m,w;
struct node
{
int from,to,cost;
node(int a,int b,int c):from(a),to(b),cost(c){}
};///边的结构体
vector<int>G[MAXN];///G[i]中的元素代表以i为起点的边
vector<node>edges;///存放所有的边
bool inq[MAXN];
int d[MAXN],cnt[MAXN];
bool SPFA(int s)
{
for(int i=0;i<=n;i++)d[i]=INF;
memset(inq,0,sizeof(inq));
memset(cnt,0,sizeof(cnt));///初始化
d[s]=0;
inq[s]=true;
queue<int> q;
q.push(s);
while(!q.empty())
{
int u=q.front();q.pop();
inq[u]=false;
for(int i=0;i<G[u].size();i++)///对以队首为起点的边进行松弛
{
node& e=edges[G[u][i]];
if(d[u]<INF&&d[e.to]>d[u]+e.cost)
{
d[e.to]=d[u]+e.cost;
if(!inq[e.to])///每松弛一个点加入队列
{
q.push(e.to);
inq[e.to]=true;
if(++cnt[e.to]>n)return false;///如果一个点被松弛n次以上说明有负环
}
}
}
}
return true;
}
void AddEdge(int from,int to,int dist)
{
edges.push_back(node(from,to,dist));
int k = edges.size();
G[from].push_back(k-1);///初始化边,将他们编号
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&w);
for(int i=1;i<MAXN;i++)G[i].clear();
edges.clear();
for(int i=0;i<m;i++)
{
int u,v,cost;
scanf("%d%d%d",&u,&v,&cost);
AddEdge(u,v,cost);AddEdge(v,u,cost);///这里路径是双向的(我这里被卡很久)
}
for(int i=0;i<w;i++)
{
int u,v,cost;
scanf("%d%d%d",&u,&v,&cost);
AddEdge(u,v,-cost);///虫洞权值为负,且为单向
}
if(!SPFA(1))printf("YES\n");
else printf("NO\n");
}
return 0;
}