本题依旧跟上题一样,可以运用bellman_ford和spfa来做,但是跟上题不同的是,本题是判断负圈,所以在初始化dis时应该初始化为INF,然后在判断时也要用大于号来进行判断,另外关于spfa有另一种方法,使用head来存上一个节点的序号,但上一题的做法莫名wa,以后就用存头节点的方法来做
bellman_ford:
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=600+10;
const int N=6000;
const int INF=10000000;
int dis[maxn],len,n;
struct node
{
int u,v,c;
}p[N];
void add(int a,int b,int c)
{
p[len].u=a;
p[len].v=b;
p[len++].c=c;
}
bool bell_man(int x)
{
dis[x]=0;
for(int i=1;i<n;i++)
{
bool flag=false;
for(int j=0;j<len;j++)
{
//cout<<"here"<<endl;
int u=p[j].u,v=p[j].v,c=p[j].c;
if(dis[u]>dis[v]+c)
{
dis[u]=dis[v]+c;
flag=true;
}
}
if(!flag)
break;
}
for(int i=0;i<len;i++)
if(dis[p[i].u]>dis[p[i].v]+p[i].c)
return true;
return false;
}
void init()
{
len=0;
for(int i=1;i<=n;i++)
{
dis[i]=INF;
}
}
int main()
{
int m,w,a,b,c,t;
//freopen("F.txt","r",stdin);
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&w);
init();
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
while(w--)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,-c);
}
if(bell_man(1))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
spfa
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
const int maxn=500+10;
const int N=6000;
const int INF=10000000;
int dis[maxn],vis[maxn],head[maxn],len,n;
int count[maxn];//记录一个点入队列的次数
struct node
{
int v,c,next;
}p[N];
void add(int a,int b,int c)
{
p[len].v=b;
p[len].c=c;
p[len].next=head[a];
head[a]=len++;
}
bool spfa(int x)
{
stack<int> q;
q.push(x);
dis[x]=0;
vis[x]=1;
count[x]++;
while(!q.empty())
{
int u=q.top();
q.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=p[i].next)
{
int v=p[i].v;
if(dis[v]>dis[u]+p[i].c)
{
dis[v]=dis[u]+p[i].c;
if(vis[v]) continue;
vis[v]=1;
count[v]++;
q.push(v);
if(count[v]>=n)//图中有负环
return true;
}
}
}
return false;
}
void init()
{
len=0;
for(int i=1;i<=n;++i)
{
count[i]=0;
dis[i]=INF;
vis[i]=0;
}
memset(head,-1,sizeof(head));
}
int main()
{
int m,w,a,b,c,i,t;
// freopen("F.txt","r",stdin);
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&w);
init();
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
while(w--)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,-c);
}
if(spfa(1))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}