P3385 【模板】负环

P3385 【模板】负环


bfs—spfa太慢,对于判负环

就只能用dfs—spfa

判负环的依据,具体会体现在code中

还有一道题也是判环

思路也是类似

我的思路

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct node
{
	int point;
	int nxt;
	int weight;
};
int head[500000],tail;
node line[500000];
int dis[500000];
int vis[500000];
bool flag;
void add(int a,int b,int c)
{
	line[++tail].point=b;
	line[tail].nxt=head[a];
	line[tail].weight=c;
	head[a]=tail;
}
void spfa(int x)
{
	vis[x]=true;
	for(int i=head[x];i;i=line[i].nxt)
	{
		if(dis[line[i].point]>dis[x]+line[i].weight)
		{
			if(vis[line[i].point]||flag)
			{
				flag=true;
				return ;
			}
			dis[line[i].point]=dis[x]+line[i].weight;
			spfa(line[i].point);
		}
	}
	vis[x]=false;
}
int main()
{
	int t;
	scanf("%d",&t);
	for(int l=1;l<=t;l++)
	{
		int n,m;
		memset(vis,0,sizeof(vis));
		memset(dis,0,sizeof(dis));//全置为0,这样正数边权就会被dfs时剪掉。只留下负数边权
		memset(head,0,sizeof(head));
		tail=0;
		flag=false;
		scanf("%d%d",&n,&m);
		int a,b,c;
		for(int i=1;i<=m;i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			if(c>=0)
			{
				add(a,b,c);
				add(b,a,c);
			}
			else
				add(a,b,c);
		}
		for(int i=1;i<=n;i++)
		{
			spfa(i);//每个点一个跑一边
                        //不过为什么是正确的呢?
                        //如果和一个点与之相连的边都是正数,我们根本不能确定它是不是在负权环上
                        //但是如果一条边是负数,它有很大可能在负权边上。大体理会下[]~( ̄▽ ̄)~*
			if(flag)
				break;
		}
		if(flag)
			printf("YE5
");
		else
			printf("N0
");	
	}
}
/*
3 4
1 2 2
1 3 4
2 3 1
3 1 -3
3 3
1 2 3
2 3 4
3 1 -8

*/
原文地址:https://www.cnblogs.com/Lance1ot/p/8708727.html