链式前向星+spfa判断负权

该题题解:

判断有没有负权产生,即从一个点到一个点的权值是否为负

题目:

Wormholes(判断是否存在负环)_#define


Wormholes(判断是否存在负环)_#include_02


该题题意:

求从1—某点,然后有虫洞再回到1,是否有负权产生

AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define maxn 10005
using namespace std;
struct node
{
int to;//终点
int next;//寻址
int val;//权值
}graph[maxn];
int head[maxn];
int book[maxn];
int dis[maxn];
int n,m,w,cnt;//n个点,m条双向边,w条单向虫洞

void inputs(int u,int v,int w)
{ //scanf("%d %d",&u,&v);
graph[cnt].to=v;
graph[cnt].val=w;
graph[cnt].next=head[u];
head[u]=cnt;
cnt++;
}

bool spfa(int s)
{
queue<int>q;
memset(book,0,sizeof(book));
memset(dis,0x3f3f3f3f,sizeof(dis));
dis[s]=0;
//book[s]=0;
q.push(s);//入队
while(!q.empty())
{
int st=q.front();
q.pop();
book[st]=0;
for(int k=head[st];k!=-1;k=graph[k].next)
{
int to=graph[k].to;
int w=graph[k].val;
if(dis[to]>dis[st]+w)
{

dis[to]=dis[st]+w;
if(book[to]==0)
{
book[to]==1;
q.push(to);

}
}
}
if(dis[1]<0)//在入队的过程中回到了1的位置的点是否有小于0的
return true;
}
return false;
}
int main()
{

int t;
scanf("%d",&t);
while(t--)
{
cnt=0;
memset(head,-1,sizeof(head));
scanf("%d %d %d",&n,&m,&w);
while(m--)
{
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
inputs(u,v,w);
inputs(v,u,w);
}
while(w--)
{ int u,v,w;
scanf("%d %d %d",&u,&v,&w);
inputs(u,v,-w);
}
if(spfa(1))
{
printf("YES\n");

}
else
printf("NO\n");
}
}