POJ Wormholes (SPFA)

http://poj.org/problem?id=3259

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.. MW+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.

SPFA判断是否有负权,如果一个点进入队列的次数达到总点数则说明有负权

dist[i]数组记录源点到i的最短路径,与Dijsktar不同的是dist[i]多次更新

use[i]记录i点进入队列的次数,即dist[i]被更新的次数;

vis[i]标记i点是否进入队列

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<queue>
#define INF 0xffffff
#define N 520
using namespace std;

struct node
{
    int e, w;
};

vector<node>G[N];
int n, use[N], dist[N];
bool vis[N];

void Init()
{
    int i;
    memset(vis, false, sizeof(vis));
    memset(use, 0, sizeof(use));
    for(i = 0 ; i <= n ; i++)
    {
        G[i].clear();
        dist[i] = INF;
    }
}

int SPFA(int s)
{
    queue<node>Q;
    node now, next;
    int i, len;
    now.e = s;
    now.w = 0;
    dist[s] = 0;
    Q.push(now);
    vis[s] = true;
    use[now.e]++;
    while(!Q.empty())
    {
        now = Q.front();
        Q.pop();
        vis[now.e] = false;

        len = G[now.e].size();
        for(i = 0 ; i < len ; i++)
        {
            next = G[now.e][i];
            if(dist[next.e] > dist[now.e] + next.w)
            {
                dist[next.e] = dist[now.e] + next.w;
                use[next.e]++;
                if(use[next.e] >= n)
                    return 1;
                if(!vis[next.e])
                {
                    vis[next.e] = true;
                    Q.push(next);
                }
            }
        }
    }
    return 0;
}

int main()
{
    int T, m, w, s, e, t, i;
    node p;
    scanf("%d", &T);
    while(T--)
    {

        scanf("%d%d%d", &n, &m, &w);
        Init();
        for(i = 1 ; i <= m ; i++)
        {
            scanf("%d%d%d", &s, &e, &t);
            p.w = t;
            p.e = s;
            G[e].push_back(p);
            p.e = e;
            G[s].push_back(p);
        }
        for(i = 1 ; i <= w ; i++)
        {
            scanf("%d%d%d", &s, &e, &t);
            p.w = -t;
            p.e = e;
            G[s].push_back(p);
        }
        if(SPFA(1))
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}
时间: 2024-10-21 20:52:54

POJ Wormholes (SPFA)的相关文章

POJ 1860(spfa)

http://poj.org/problem?id=1860 题意:汇率转换,与之前的2240有点类似,不同的是那个题它去换钱的时候,是不需要手续费的,这个题是需要手续费的,这是个很大的不同. 思路:还是转换成为最短路的问题,主要的困难也就是关于它的松弛方程.dist [edge[i].v] < (dist[ tmp ] - edge[ i ].r) * edge[ i ].c  .这个就是松弛方程,当它的钱的数目增多的时候松弛. 1 #include <stdio.h> 2 #incl

poj 3259 Wormholes (Bellman-ford)

链接: poj 3259 题意:一个famer有一些农场,这些农场里面有一些田地,田地里面有一些虫洞,田地和田地之间有路(双向的),即从a到b和从b到a时间都为c.虫洞的性质:时间倒流.即通过虫洞从a到b所花时间为 -c(单向的).问从某块田出发,他能否通过虫洞的性质回到出发点前 思路:这题实际就是判断是否存在负权回路,可以用SPFA算法或Bellman-Ford算法判断.若存在负权回路,则可以达到目的,否则不可以. Bellman-ford算法 #include<stdio.h> #incl

POJ 3259 Wormholes(SPFA)

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! Eac

poj 1860 Currency Exchange(SPFA)

题目链接:http://poj.org/problem?id=1860 Description Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with these currencies. There can b

POJ 2253-Frogger (Prim)

题目链接:Frogger 题意:两只青蛙,A和B,A想到B哪里去,但是A得弹跳有限制,所以不能直接到B,但是有其他的石头作为过渡点,可以通过他们到达B,问A到B的所有路径中,它弹跳最大的跨度的最小值 PS:最小生成树过的,刚开始用Dijstra做,Kao,精度损失的厉害,对于Dijksra的变形不大会变啊,看了Discuss有人用最小生成树过,我一划拉,还真是,敲了,就过了,等会研究研究最短路的各种变形,有模板不会变,不会灵活应用,渣渣就是渣渣. ME               Time 10

poj 1861(最小生成树)

Description Andrew is working as system administrator and is planning to establish a new network in his company. There will be N hubs in the company, they can be connected to each other using cables. Since each worker of the company must have access

HDU 2680Choose the best route (SPFA)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2680 百度之星编程大赛--您报名了吗? 杭电ACM 2014暑期集训队--选拔安排~ Choose the best route Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis

模板C++ 03图论算法 1最短路之单源最短路(SPFA)

3.1最短路之单源最短路(SPFA) 松弛:常听人说松弛,一直不懂,后来明白其实就是更新某点到源点最短距离. 邻接表:表示与一个点联通的所有路. 如果从一个点沿着某条路径出发,又回到了自己,而且所经过的边上的权和小于0, 就说这条路是一个负权回路. 回归正题,SPFA是bellman-ford的一种改进算法,由1994年西安交通大学段凡丁提出.它无法处理带有负环的图,判断方法:如果某个点进入队列的次数超过N次则存在负环. SPFA的两种写法,bfs和dfs,bfs判别负环不稳定,相当于限深度搜索

POJ 2352 (stars)

[题意描述] 就是给定n个星星的x,y坐标,y坐标按照从小到大的顺序进行排列,x坐标随机排列.下面求对于每个星星而言,其它星星的x,y的坐标都小于等于该星星的数目,然后输出所有的情况. [思路分析] 我们这道题可以采用树状数组求解,将x+1作为树状数组的底标. [AC代码] #include<iostream> #include<bitset> #include<cstdio> #include<cstring> #include<algorithm&