大意:虫洞旅行,前面一部分(n组)是双向正权,后面一部分(w组)是单向负权,判断有没有负权环。
思路:由于有负权边,就不能Dijkstra了,用Bellman_Ford。就是看图中有没有负权环,有的话可以无限次走这个环,使得时间一定能得到一个负值。所以有的存在负环话就是可以,没有的话就是不可以了。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Max = 10001
struct node
{
int s, e, t;
} q[5010];
int dis[520];
bool Bellman_Ford(int n, int r)
{
memset(dis, 0, sizeof(dis));
for(int i = 1; i <= n; i++)
{
bool flag = false;
for(int j = 1; j <= r; j++)
{
if(dis[q[j].e] > dis[q[j].s]+q[j].t)
{
dis[q[j].e] = dis[q[j].s]+q[j].t;
flag = true;
}
}
if(!flag)
{
break;
}
}
for(int i = 1; i <= r; i++)
{
if(dis[q[i].e] > dis[q[i].s]+q[i].t)
{
return true;
}
}
return false;
}
void Solve()
{
int p, n, m, w, a, b, c;
scanf("%d", &p);
while(p--)
{
scanf("%d%d%d", &n, &m, &w);
int r = 0;
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d", &a, &b, &c);
q[++r].s = a;
q[r].e = b;
q[r].t = c;
q[++r].s = b;
q[r].e = a;
q[r].t = c;
}
for(int i = 1; i <= w; i++)
{
scanf("%d%d%d", &a, &b, &c);
q[++r].s = a;
q[r].e = b;
q[r].t = -c;
}
if(Bellman_Ford(n, r))
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
}
int main()
{
Solve();
return 0;
}