POJ 3259 Wormholes
题意:FJ发现了许多虫洞,通过虫洞可以使时光倒流,通过普通的路时间增加,给出一张有向带负权图,问FJ能不能从某一点出发回到这一点时回到了过去。
解法:Bellman-Ford判负环。先做n-1次松弛,得到最多用n-1条边时从源点到每一个点的最短路径,如果再做一次松弛还可以减少路径长度,说明有负环。
代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<time.h>
#include<stdlib.h>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define LL long long
using namespace std;
struct node
{
int u, v, value;
node(int u, int v, int value) : u(u), v(v), value(value) {}
node() {}
} edge[5300];
int n, m, w, cnt;
int dis[505];
const int inf = 0x3f3f3f3f;
bool BellmanFord()
{
memset(dis, inf, sizeof dis);
dis[1] = 0;
for(int i = 0; i < n - 1; i++)
for(int j = 0; j < cnt; j++)
dis[edge[j].v] = min(dis[edge[j].u] + edge[j].value, dis[edge[j].v]);
for(int i = 0; i < cnt; i++)
{
if(dis[edge[i].v] > dis[edge[i].u] + edge[i].value)
return 1;
}
return 0;
}
int main()
{
int T;
while(~scanf("%d", &T))
{
while(T--)
{
cnt = 0;
scanf("%d%d%d", &n, &m, &w);
for(int i = 0; i < m; i++)
{
int u, v, value;
scanf("%d%d%d", &u, &v, &value);
edge[cnt++] = node(u, v, value);
edge[cnt++] = node(v, u, value);
}
for(int i = 0; i < w; i++)
{
int u, v, value;
scanf("%d%d%d", &u, &v, &value);
edge[cnt++] = node(u, v, -value);
}
if(BellmanFord())
puts("YES");
else
puts("NO");
}
}
return 0;
}

浙公网安备 33010602011771号