题目问从1开始 通过一些正权边和负权边,权值为走这条边的耗时,问能否在负数时间内回到原点,
也就是判断是否存在负环啦,
spfa+邻接表的方式判负环,因为用了邻接表,重边可以不特别处理
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
int n,m,w;
const int inf=0x7F7f7f7f;
struct node
{
int x,v;
node(){}
node(int a,int b)
{
x=a;
v=b;
}
bool operator <(const node&b) const
{
return v>b.v; //*****
}
};
vector <node> mp[508];
int st;
int ed;
int dis[508];
int in[508];
int main()
{
int i;
int t;
while(cin>>t)
{
int s,e,tt;
bool spfa();
while(t--)
{
for (i=1;i<=n;i++)
mp[i].clear();
scanf("%d%d%d",&n,&m,&w);
for (i=1;i<=m;i++)
{
scanf("%d%d%d",&s,&e,&tt);
// if (mp[s][e]!=inf &&tt>=mp[s][e]) continue;
mp[s].push_back(node(e,tt));
mp[e].push_back(node(s,tt));
}
for (i=1;i<=w;i++)
{
scanf("%d%d%d",&s,&e,&tt);
tt=-tt;
// if (mp[s][e] &&tt>=mp[s][e]) continue;
mp[s].push_back(node(e,tt));
}
st=1;
bool flag=spfa();
printf("%s\n",flag?"YES":"NO");
}
}
return 0;
}
queue<node>q;
int vis[508];
bool spfa()
{
while(!q.empty()) q.pop();
int i;
for (i=1;i<=n;i++)
{
dis[i]=inf;
vis[i]=0;
in[i]=0;
}
dis[st]=0;
vis[st]=1;
in[st]=1;
q.push(node(st,0));
while(!q.empty())
{
node tmp=q.front();
q.pop();
int tt=tmp.x;
vis[tt]=0;
for (i=0;i<mp[tt].size();i++)
{
int x=mp[tt][i].x;
int v=mp[tt][i].v;
if (dis[tt]+v<dis[x])
{
dis[x]=dis[tt]+v;
if (!vis[x])
{
q.push(node(x,dis[x]));
vis[x]=1;
}
in[x]++;
if (in[x]>n) //入队n次表存在负环
return true;
}
}
}
return false;
}