/*
给你一副图,能否从一点出发,回到起点,距离为负,
floyd跑一遍,看自己到自己的距离会不会为负数
500*500*500 12500,0000应该可以,然而无情tle
这个难道只要有负环就是yes了?
试一下SPFA
居然真的是,然后就re了,因为队列开太小了
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define Max(a,b) (a)>(b)?(a):(b)
#define Min(a,b) (a)<(b)?(a):(b)
#define oo 0x3f3f3f3f
const int maxn = 1010;
int mp[maxn][maxn];
int n,m,w,flag;
int dis[maxn],out[maxn],vis[maxn];
int que[maxn*maxn],ts,te;
void Floyd()
{
for(int k = 1; k <= n; k++)
{
for(int u = 1; u <= n; u++)
{
for(int v = 1; v <= n; v++)
{
if(mp[u][k]!=oo&&mp[k][v]!=oo)
{
mp[u][v] = Min(mp[u][v], mp[u][k]+mp[k][v]);
if(u == v &&mp[u][v] < 0)
{
flag = 1;
return;
}
}
}
}
}
}
bool Spfa(int s)
{
for(int i = 1; i <= n; i++)
dis[i] = oo;
memset(vis,0,sizeof(vis));
memset(out,0,sizeof(out));
dis[s] = 0;
vis[s] = 1;
ts = te = 0;
que[ts++] = s;
while(te!=ts)
{
int top = que[te++];
vis[top] = 0;
out[top]++;
if(out[top]>n)return 1;
for(int i = 1; i <= n; i++)
{
if(dis[i]>dis[top]+mp[top][i])
{
dis[i] = dis[top]+mp[top][i];
if(!vis[i])
{
vis[i] = 1;
que[ts++] = i;
}
}
}
}
return 0;
}
int main()
{
int f;
int s,e,t;
scanf("%d",&f);
while(f--)
{
scanf("%d%d%d",&n,&m,&w);
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
if(i == j)mp[i][j]=0;
else mp[i][j] =oo;
}
while(m--)
{
scanf("%d%d%d",&s,&e,&t);
if(mp[s][e]>t)
mp[s][e] = mp[e][s] = t;
}
while(w--)
{
scanf("%d%d%d",&s,&e,&t);
if(mp[s][e]+t>0)
mp[s][e] = -t;
}
/*flag = 0;
Floyd();*/
if(Spfa(1))puts("YES");
else puts("NO");
}
return 0;
}
最短路_POJ_3259
最新推荐文章于 2018-10-13 00:42:51 发布