POJ3259Wormholes(bellman-ford找负环)

题意杀….

题意:给n+w个顶点和m条边,边的信息为时间,其中w表示虫洞,边的时间取负数代表可以回到过去,问时间能不能回到过去

题解:给出的n个顶点和边是双向的,而虫洞是单向并且边权值取负值,建图然后bellman-ford判负环就好了

<span style="font-size:14px;">#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
using namespace std;
#define maxn 505
#define LL long long
int cas=1,T;
int n,m,w;
const int INF = 1<<29;
struct Edge
{
	int from,to,dist;
	Edge(int u,int v,int d):from(u),to(v),dist(d){}
};
struct Bellman_ford
{
	vector<Edge>edges;
	vector<int> G[maxn];
	int d[maxn];
    int inq[maxn];
	int cnt[maxn];
	void init()
	{
       for (int i = 0;i<=n;i++)
		   G[i].clear();
	   edges.clear();
	}
	void AddEdge(int from,int to,int dist)
	{
       edges.push_back(Edge(from,to,dist));
	   int mm = edges.size();
	   G[from].push_back(mm-1);
	}
	bool bellman_ford(int s)
	{
		queue<int>q;
		memset(inq,0,sizeof(inq));
		memset(cnt,0,sizeof(cnt));
		for (int i =0;i<=n;i++)
		   d[i]=INF;
		d[s]=0;
		inq[s]=1;
		q.push(s);
		while (!q.empty())
		{
			int u = q.front();q.pop();
			inq[u] = false;
			for (int i =0;i<G[u].size();i++)
			{
				Edge &e = edges[G[u][i]];
				if (d[u]<INF && d[e.to]>d[u]+e.dist)
				{
					d[e.to] = d[u] + e.dist;
					if (!inq[e.to])
					{
						q.push(e.to);
						inq[e.to]=1;
						if (++cnt[e.to]>n)
							return false;
					}
				}
			}
		}
		return true;
	}
};
int main()
{
	//freopen("in","r",stdin);
	scanf("%d",&T);
	while (T--)
	{
        scanf("%d%d%d",&n,&m,&w);
		Bellman_ford bf;
		bf.init();
		for (int i = 0;i<m;i++)
		{
			int u,v,t;
			scanf("%d%d%d",&u,&v,&t);
            bf.AddEdge(u,v,t);
			bf.AddEdge(v,u,t);
		}
		for (int i = 0;i<w;i++)
		{
			int u,v,t;
			scanf("%d%d%d",&u,&v,&t);
			bf.AddEdge(u,v,-t);
		}
		if (!bf.bellman_ford(1))
			puts("YES");
		else
			puts("NO");
	}
	//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
	return 0;
}</span>

题目

Description

While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination at a time that is BEFORE you entered the wormhole! Each of FJ’s farms comprises N (1 ≤ N ≤ 500) fields conveniently numbered 1..NM (1 ≤ M ≤ 2500) paths, and W (1 ≤ W ≤ 200) wormholes.

As FJ is an avid time-traveling fan, he wants to do the following: start at some field, travel through some paths and wormholes, and return to the starting field a time before his initial departure. Perhaps he will be able to meet himself :) .

To help FJ find out whether this is possible or not, he will supply you with complete maps to F (1 ≤ F ≤ 5) of his farms. No paths will take longer than 10,000 seconds to travel and no wormhole can bring FJ back in time by more than 10,000 seconds.

Input

Line 1: A single integer, 
F
F farm descriptions follow. 

Line 1 of each farm: Three space-separated integers respectively: 
N
M, and 
W

Lines 2.. 
M+1 of each farm: Three space-separated numbers ( 
S
E
T) that describe, respectively: a bidirectional path between 
S and 
E that requires 
T seconds to traverse. Two fields might be connected by more than one path. 

Lines 
M+2.. 
M
W+1 of each farm: Three space-separated numbers ( 
S
E
T) that describe, respectively: A one way path from 
S to 
E that also moves the traveler back 
T seconds.

Output

Lines 1.. 
F: For each farm, output “YES” if FJ can achieve his goal, otherwise output “NO” (do not include the quotes).

Sample Input

2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8

Sample Output

NO
YES

Hint

For farm 1, FJ cannot travel back in time. 

For farm 2, FJ could travel back in time by the cycle 1->2->3->1, arriving back at his starting location 1 second before he leaves. He could start from anywhere on the cycle to accomplish this.

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/qq_21057881/article/details/50571750
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞