P3385 【模板】负环 spfa判断负环
作者:互联网
题目描述
暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索
寻找一个从顶点1所能到达的负环,负环定义为:一个边权之和为负的环。
输入输出格式
输入格式:
第一行一个正整数T表示数据组数,对于每组数据:
第一行两个正整数N M,表示图有N个顶点,M条边
接下来M行,每行三个整数a b w,表示a->b有一条权值为w的边(若w<0则为单向,否则双向)
输出格式:
共T行。对于每组数据,存在负环则输出一行"YE5"(不含引号),否则输出一行"N0"(不含引号)。
输入输出样例
输入样例#1: 复制
2
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
输出样例#1: 复制
N0
YE5
说明
2000n≤2000
3000m≤3000
−10000≤w≤10000
10T≤10
建议复制输出格式中的字符串。 本题数据感谢@negiizhao的精心构造,请不要使用玄学算法 本题数据有更新
这个题的输出坑的一匹 输出是YE5 和N0
然后就是通过判断他出现的次数有没有大于n 出现次数大于n就表示有负环
#include<bits/stdc++.h>
using namespace std;
#define INF 2147483647;
const int maxn=10005;
const int maxm=500005;
int n,m,s,cnt,x,y,z,c[60005];
int dis[20005],vis[20005],head[60005];
struct node
{
int x,y,sum,next;
}e[60005];
void add(int x,int y,int sum)
{
cnt++;
e[cnt].x=x;
e[cnt].y=y;
e[cnt].sum=sum;
e[cnt].next=head[x];
head[x]=cnt;
}
int spfa()
{
queue<int>q;
for(int i=1;i<=n;i++)
dis[i]=INF;
dis[1]=0;
memset(vis,0,sizeof(vis));
memset(c,0,sizeof(c));
q.push(1);//入队
vis[1]=1;//初始化
while(!q.empty())
{
int u=q.front();
q.pop();//出队
vis[u]=0;//出队标记
for(int i=head[u];i;i=e[i].next)//所有u能走的路
{
int v=e[i].y;
if(dis[v]>dis[u]+e[i].sum)
{
dis[v]=dis[u]+e[i].sum;//取最小的
c[v]++;//更新
if(c[v]>n) return 0;//出现超过n次表示就有负环
if(vis[v]==0)//如果这个点没在队列里就标记入队
{
vis[v]=1;
q.push(v);
}
}
}
}
return 1;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>m;
memset(head,0,sizeof(head));
for(int i=1;i<=m;i++)
{
cin>>x>>y>>z;
add(x,y,z);
if(z>=0)
add(y,x,z);
}
if(spfa()==0) cout<<"YE5"<<endl;
else cout<<"N0"<<endl;
}
return 0;
}
标签:输出,cnt,int,sum,spfa,负环,P3385,head 来源: https://blog.csdn.net/tjndsg/article/details/88955079