Wormholes (poj 3259 SPFA || Bellman_Ford 判负环)

Language: Default Wormholes

Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 33291 Accepted: 12130

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,  FF farm descriptions follow. 
Line 1 of each farm: Three space-separated integers respectively:  NM, and  W 
Lines 2.. M+1 of each farm: Three space-separated numbers ( SET) 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 ( SET) 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.

Source

USACO 2006 December Gold


题意:John的农场里field块地,path条路连接两块地,hole个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。我们的任务是知道会不会在从某块地出发后又回来,看到了离开之前的自己。

很久之前做的最短路,今天又写了一遍,复习了一下SPFA和Bellma_Ford,判断负权值回路。

代码:

//Bellman_Ford
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 550
#define MAXN 2005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b)  for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b)  for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define DBG         pf("Hi\n")
typedef long long ll;
using namespace std;

struct Edge
{
    int u,v,w;
}edge[maxn*10];

int n,m,w,num;
int dist[maxn];

bool Bellman_Ford()
{
    int i,j;
    FRL(i,0,n+2)
        dist[i]=INF;
    dist[1]=0;
    FRL(i,1,n)
    {
        bool flag=false;
        FRL(j,0,num)
        {
            int u=edge[j].u;
            int v=edge[j].v;
            if (dist[v]>dist[u]+edge[j].w)
            {
                flag=true;
                dist[v]=dist[u]+edge[j].w;
            }
        }
        if (!flag) return true;
    }
    FRL(i,0,num)
        if (dist[ edge[i].v ]>dist[ edge[i].u ]+edge[i].w)
            return false;
    return true;
}

int main()
{
    int i,j,cas;
    sf(cas);
    while (cas--)
    {
        num=0;
        int u,v,t;
        sfff(n,m,w);
        FRL(i,0,m)
        {
            sfff(u,v,t);
            edge[num].u=u;
            edge[num].v=v;
            edge[num].w=t;
            num++;
            edge[num].u=v;
            edge[num].v=u;
            edge[num].w=t;
            num++;
        }
        FRL(i,0,w)
        {
            sfff(u,v,t);
            edge[num].u=u;
            edge[num].v=v;
            edge[num].w=-t;
            num++;
        }
        if (Bellman_Ford())
            pf("NO\n");
        else
            pf("YES\n");
    }
    return 0;
}

//SPFA
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 550
#define MAXN 2005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b)  for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b)  for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define DBG         pf("Hi\n")
typedef long long ll;
using namespace std;

struct Edge
{
    int v,w;
    int next;
}edge[maxn*10];

int n,m,w,num;
int head[maxn];
int dist[maxn];
bool inq[maxn];
int cnt[maxn];

void init()
{
    num=0;
    mem(head,-1);
    mem(inq,false);
    mem(cnt,0);
    mem(dist,INF);
}

void addedge(int u,int v,int w)
{
    edge[num].v=v;
    edge[num].w=w;
    edge[num].next=head[u];
    head[u]=num++;
}

bool SPFA()
{
    queue<int>Q;
    inq[1]=true;
    cnt[1]=1;
    dist[1]=0;
    while (!Q.empty()) Q.pop();
    Q.push(1);
    while (!Q.empty())
    {
        int u=Q.front(); Q.pop();
        inq[u]=false;
        if (cnt[u]>n)
            return false;
        for (int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if (dist[v]>dist[u]+edge[i].w)
            {
                dist[v]=dist[u]+edge[i].w;
                if (!inq[v])
                {
                    inq[v]=true;
                    cnt[v]++;
                    Q.push(v);
                }
            }
        }
    }
    return true;
}

int main()
{
    int i,j,cas;
    sf(cas);
    while (cas--)
    {
        int u,v,t;
        init();
        sfff(n,m,w);
        FRL(i,0,m)
        {
            sfff(u,v,t);
            addedge(u,v,t);
            addedge(v,u,t);
        }
        FRL(i,0,w)
        {
            sfff(u,v,t);
            addedge(u,v,-t);
        }
        if (SPFA())
            pf("NO\n");
        else
            pf("YES\n");
    }
    return 0;
}

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