题目传送门:https://www.luogu.org/problemnew/show/P3385
题意:
有n个点,m条边,求是否存在负环。
坑处1:有负环,输出YE5(请看清楚),否则输出N0(请看清楚)。
附:这是S,这是5;这是O,这是0。
思路1:
很明显用dfs判负环吗,这样更快。
可是被卡了。
代码:
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
queue<int> f;
int n,m,len,st=1;
struct node{int x,y,z,next;} a[15000];
int last[4010],dis[4010],tot[4010];
bool bz[4010];
void ins(int x,int y,int z)
{
a[++len].x=x;a[len].y=y;a[len].z=z;a[len].next=last[x];last[x]=len;
}
bool spfa()
{
memset(bz,true,sizeof(bz));
bz[st]=false;
memset(dis,63,sizeof(dis));
dis[st]=0;
memset(tot,0,sizeof(tot));
f.push(st);
while(!f.empty())
{
int x=f.front();
f.pop();
bz[x]=true;
for(int i=last[x];i;i=a[i].next)
{
int y=a[i].y;
if(dis[x]+a[i].z<dis[y])
{
dis[y]=dis[x]+a[i].z;
if(bz[y])
{
if(++tot[y]>n) return true;
bz[y]=false;
f.push(y);
}
}
}
}
return false;
}
int main()
{
int T,x,y,t;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
len=0;
memset(last,0,sizeof(last));
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&x,&y,&t);
ins(x,y,t);
if(t>=0) ins(y,x,t);
}
printf(spfa()?"YE5\n":"N0\n");
}
}
思路2:
很无语。
翻题解。
发现一种奇怪的做法。
正确性不知。
1.将dis数组初始化为0(本来为正无穷);
2.如果被松弛n次,则为负环(本来是入队列n次,则为负环)。
代码:
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
queue<int> f;
int n,m,len,st=1;
struct node{int x,y,z,next;} a[15000];
int last[4010],dis[4010],tot[4010];
bool bz[4010];
void ins(int x,int y,int z)
{
a[++len].x=x;a[len].y=y;a[len].z=z;a[len].next=last[x];last[x]=len;
}
bool spfa()
{
memset(bz,true,sizeof(bz));
bz[st]=false;
memset(dis,63,sizeof(dis));
dis[st]=0;
memset(tot,0,sizeof(tot));
f.push(st);
while(!f.empty())
{
int x=f.front();
f.pop();
bz[x]=true;
for(int i=last[x];i;i=a[i].next)
{
int y=a[i].y;
if(dis[x]+a[i].z<dis[y])
{
dis[y]=dis[x]+a[i].z;
if(bz[y])
{
if(++tot[y]>n) return true;
bz[y]=false;
f.push(y);
}
}
}
}
return false;
}
int main()
{
int T,x,y,t;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
len=0;
memset(last,0,sizeof(last));
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&x,&y,&t);
ins(x,y,t);
if(t>=0) ins(y,x,t);
}
printf(spfa()?"YE5\n":"N0\n");
}
}