码迷,mamicode.com
首页 > 其他好文 > 详细

「POJ3259」Wormholes - SPFA判负环

时间:2018-09-26 20:46:48      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:tput   dig   anywhere   rate   ++   href   let   follow   git   

->戳我进原题

Wormholes


Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 65211 Accepted: 24284


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..N, M (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.

农夫约翰在探索他的许多农场,发现了一些惊人的虫洞。虫洞是很奇特的,因为它是一个单向通道,可让你进入虫洞的前达到目的地!他的 \(N(1≤N≤500)\) 个农场被编号为 \(1\)..\(N\),之间有 \(M(1≤M≤2500)\) 条路径,\(W(1≤W≤200)\) 个虫洞。作为一个狂热的时间旅行 \(FJ\) 的爱好者,他要做到以下几点:开始在一个区域,通过一些路径和虫洞旅行,他要回到最开时出发的那个区域出发前的时间。也许他就能遇到自己了:)。为了帮助 \(FJ\) 找出这是否是可以或不可以,他会为你提供 \(F\) 个农场的完整的映射到 \((1≤F≤5)\) 。所有的路径所花时间都不大于 \(10000\) 秒,所有的虫洞都不大于万秒的时间回溯。

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.

\(1\) 行:一个整数 \(F\) 表示接下来会有 \(F\) 个农场说明。
每个农场第一行:分别是三个空格隔开的整数: \(N\)\(M\)\(W\)
\(2\) 行到 \(M+1\) 行:三个空格分开的数字 \((S,E,T)\) 描述,分别为:需要 \(T\) 秒走过 \(S\)\(E\) 之间的双向路径。两个区域可能由一个以上的路径来连接。
\(M +2\)\(M+ W+1\) 行:三个空格分开的数字 \((S,E,T)\) 描述虫洞,描述单向路径, \(S\)\(E\) 且回溯 \(T\) 秒。

Output

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

\(F\) 行,每行代表一个农场
每个农场单独的一行, “\(YES\)”表示能满足要求,”\(NO\)”表示不能满足要求。

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.

思路

想要回到原点,虫洞让你回到过去(饥荒玩家表示b这并不能),相当于一个负权,然后判断f是否存在负环即可。

代码

#include<cstdio>
#include<cctype>
#include<iostream>
#include<queue>
#include<cstring>
#define rg register
#define int long long
using namespace std;
inline int read(){
    rg int f = 0, x = 0;
    rg char ch = getchar();
    while(!isdigit(ch)) f |= (ch == '-'), ch = getchar();
    while( isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    return f? -x: x;
}
const int N = 6010;
const int inf = 0x7f7f7f7f;
int T, n, m, k, head[N], tot, dis[N], u, v, w, cnt[N];
bool vis[N];
struct edge{
    int nxt, to, w;
}e[N << 1];
inline void init(){
    for(rg int i = 1; i <= n; ++i){
        if(vis[i])  vis[i] = 0;
        if(head[i]) head[i] = 0;
        if(cnt[i])  cnt[i] = 0;
    }
    memset(e, 0, sizeof(e));
    tot = 0;
}
inline void add(rg int u, rg int v, rg int w){
    e[++tot].nxt = head[u];
    e[tot].to = v;
    e[tot].w = w;
    head[u] = tot;
}
inline bool spfa(){
    for(rg int i = 1; i <= n; ++i)  dis[i] = inf;
    queue<int > q;
    dis[1] = 0;
    vis[1] = 1;
    q.push(1);
    while(!q.empty()){
        int u = q.front();
        vis[u] = false;
        q.pop();
        for(rg int i = head[u]; i; i = e[i].nxt){
            int v = e[i].to;
            if(dis[v] > dis[u] + e[i].w){
                dis[v] = dis[u] + e[i].w;
                cnt[v] = cnt[u] + 1;
                if(cnt[v] >= n) return true;    //注意是 >= n 
                if(!vis[v]){
                    vis[v] = true;
                    q.push(v);
                }
            }
        }
    }
    return false;
}
signed main(){
    T = read();
    for(rg int o = 1; o <= T; ++o){
        n = read(), m = read(), k = read();
        if(o > 1)   init();
        for(rg int i = 1; i <= m; ++i){
            u = read(), v = read(), w = read();
            add(u, v, w);
            add(v, u, w);
        }
        for(rg int i = 1; i <= k; ++i){
            u = read(), v = read(), w = read();
            add(u, v, -w);
        }
        if(spfa())  puts("YES");
        else    puts("NO");
    }
    return 0;
}

「POJ3259」Wormholes - SPFA判负环

标签:tput   dig   anywhere   rate   ++   href   let   follow   git   

原文地址:https://www.cnblogs.com/horrigue/p/9709409.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!