SPFA找负环,当一个点入队的次数>=n时就证明出现了负环。

代码
#include <iostream>
#include 
<cstdio>
#include 
<cstring>
#include 
<queue>
using namespace std;
const int  N =510;
vector 
<int> map[N];
struct Edge
{
    
int to,dis;
    Edge 
* next;
};
Edge 
*adj[N];
Edge edges[N
*N*3];
int cnt;
void addEdge(int s,int e,int cost)
{
    Edge 
*ptr = &edges[cnt++];
    ptr
->to =e;
    ptr
->dis = cost;
    ptr
->next = adj[s];
    adj[s] 
= ptr;
}
int n,m;
bool vis[N];
int vCnt[N];
int dis[N];
bool spfa()
{
    queue 
<int> Q;
    memset(vis,
false,sizeof(vis));
    memset(vCnt,
0,sizeof(vCnt));
    memset(dis,
127,sizeof(dis));

    Q.push(
1);
    vCnt[
1]++;
    dis[
1= 0;
    
while(!Q.empty())
    {
        
int u = Q.front();Q.pop();
        vis[u] 
= false;
        
for(Edge *ptr =adj[u];ptr;ptr=ptr->next)
        {
            
int e = ptr->to;
            
int cost = ptr->dis;
            
if(dis[e]>dis[u]+cost)
            {
                dis[e] 
= dis[u] + cost;
                
if(!vis[e])
                {
                    Q.push(e);
                    vis[e] 
= true;
                    vCnt[e]
++;
                    
if(vCnt[e]>=n)
                    {
                        
return true;
                    }
                }
            }
        }
    }
    
return false;

}
int main()
{
    
int F,w;
    scanf(
"%d",&F);
    
while(F--)
    {
        memset(adj,
0,sizeof(adj));
        cnt 
= 0;
        scanf(
"%d%d%d",&n,&m,&w);
        
int s,e,cost;
        
for(int i=1;i<=m;i++)
        {
            scanf(
"%d%d%d",&s,&e,&cost);
            addEdge(s,e,cost);
            addEdge(e,s,cost);
        }
        
for(int i=1;i<=w;i++)
        {
            scanf(
"%d%d%d",&s,&e,&cost);
            addEdge(s,e,
-cost);
        }
        spfa()
?printf("YES\n"):printf("NO\n");
    }
    
return 0;
}