
直接spfa判负环即可,判断每个点入队的次数是否大于n
代码
#include<bits/stdc++.h>
using namespace std;
const int maxm=2705;
const int maxn=505;
struct edge
{
int to,nxt,v;
}e[maxm<<1];
int n,m,w;
int cnt,head[maxn],dis[maxn],flag,in[maxn],tot[maxn];
void add(int x,int y,int z)
{
e[++cnt].to=y;
e[cnt].nxt=head[x];
e[cnt].v=z;
head[x]=cnt;
}
void spfa(int s)
{
queue <int> q;
q.push(s);
in[s]=1; dis[s]=0;
while(!q.empty())
{
int u=q.front(); q.pop();
in[u]=0;
for(int i=head[u];i;i=e[i].nxt)
{
int to=e[i].to;
if(dis[to]>dis[u]+e[i].v)
{
dis[to]=dis[u]+e[i].v;
if(!in[to])
{
in[to]=1;
q.push(to);
tot[to]++;
}
if(tot[to]>n)
{
flag=1;
return;
}
}
}
}
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
int t; scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&w);
memset(head,0,sizeof(head));
memset(in,0,sizeof(in));
memset(dis,127,sizeof(dis));
memset(tot,0,sizeof(tot));
flag=0;
cnt=0;
int x,y,z;
for(int i=1;i<=m;i++) scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
for(int i=1;i<=w;i++) scanf("%d%d%d",&x,&y,&z),add(x,y,-z);
spfa(1);
if(!flag) printf("NO\n");
else printf("YES\n");
}
return 0;
}

该代码实现了一个SPFA(Shortest Path Faster Algorithm)算法,用于判断加权有向图中是否存在负环。通过队列进行广度优先搜索,记录每个节点入队次数,若超过节点数则说明存在负环。程序读取边信息和负权边信息,最后输出是否存在负环的结果。
1256

被折叠的 条评论
为什么被折叠?



