SPFA 是bellman-ford的一种优化
SPFA 用于求负权存在的最短路,判断是否有负权回路,只需判断松弛边的次数,如果大于N,就说明存在负权回路
#include<stdio.h>
#include<cstring>
#include<vector>
#include<iostream>
#include<queue>
#include<algorithm>
#define N 5501
using namespace std;
const int inf=0x7fffffff;
int map[N][N];
int d[N];
bool inq[N];
int cnt[N];
int n,m,q;
bool spfa(int s)
{
queue<int> q;
int i;
for(i=0;i<=n;i++)
d[i]=inf;
d[s]=0;
memset(inq,0,sizeof(inq));
memset(cnt,0,sizeof(cnt));
q.push(s);
inq[s]=true;
cnt[s]++;
while(!q.empty())
{
int t=q.front();
q.pop();
inq[t]=false;
for( i=1;i<=n;i++)
{
if(d[t]<inf&&map[t][i]<inf&&d[i]>d[t]+map[t][i])
{
d[i]=d[t]+map[t][i];
cnt[i]++;
if(cnt[i]>=n)
return false;
if(!inq[i])
{
q.push(i);
inq[i]=true;
}
}
}
}
return true;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&q);
int u,v,w;
int i,j;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
map[i][j]=inf;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&w);
if(map[u][v]>w)
map[u][v]=map[v][u]=w;
}
for(i=0;i<q;i++)
{
scanf("%d%d%d",&u,&v,&w);
map[u][v]=-w;
}
if(spfa(1))
printf("NO\n");
else
printf("YES\n");
}
return 0;
}