Luo Gu P2850 [USACO06DEC] Wormhole Wormholes solution to a problem

P2850 [USACO06DEC] wormhole Wormholes

Title 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.

John on his farm found in many wandering wormhole. Wormholes can be seen as a very strange directed edges, and allows you to return to a time in the past (before you enter the wormhole relative). Each farm has John M footpath (undirected edges) is connected to N (the reference numeral 1..N) block, a W and has a wormhole. Where 1 <= N <= 500,1 <= M <= 2500,1 <= W <= 200. Now John would like to use these wormholes to return to the past (before the departure time), you tell him to do it. John will provide you with F (1 <= F <= 5) Map farms. The path will cost you no more than 10,000 seconds of time, and certainly no wormhole back to help you get back more than 10,000 seconds ago.

Input Format

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 Format

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

Sample input and output

Input # 1

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

Output # 1

NO
YES

Description / Tips

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.

[Thinking]

SFPA forfeit ring
is a water ring SPFA forfeit the title of board

[Analysis] title

Back to the time consumed in no way above farmland wormhole of
time before there is a wormhole will return to the road above
is the time to get
it will reduce the time spent before
time can become negative as long as the consumption
is back to the time of departure Room
can become negative
that is a weight of a negative ring
is negative ring
so there is no need to determine only the ring can be a negative

[SPFA forfeit ring]

Board
naked a board question
details explanation see
here

[Complete code]

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int Max = 6004;
const int M = 505;
struct node
{
    int y,ne,z;
}a[Max];
int n,m,w; 
int head[M],sum = 0;

void add(int x,int y,int z)
{
    a[++ sum].y = y;
    a[sum].ne = head[x];
    a[sum].z = z;
    head[x] = sum;
}

int d[M],cnt[M];
bool use[M];
bool SPFA()
{
    memset(cnt,0,sizeof(cnt));
    memset(use,false,sizeof(use));
    for(register int i = 1;i <= n;++ i)
        d[i] = 999999;
    d[1] = 0;
    queue<int>q;
    q.push(1);
    while(!q.empty())
    {
        int qwq = q.front();
        q.pop();use[qwq] = false;
        for(register int i = head[qwq];i != 0;i = a[i].ne)
        {
            int awa = a[i].y;
            if(d[awa] > d[qwq] + a[i].z)
            {
                d[awa] = d[qwq] + a[i].z;
                cnt[awa] = cnt[qwq] + 1;
                if(cnt[awa] > n)
                    return false;
                if(use[awa] == false)
                {
                    use[awa] = true;
                    q.push(awa);
                }
            }
        }
    }
    return true;
}

int main()
{
    int f;
    scanf("%d",&f);
    while(f --)
    {
        sum = 0;
        memset(head,0,sizeof(head));
        scanf("%d%d%d",&n,&m,&w);
        int x,y,z;
        for(register int i = 1;i <= m;++ i)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);add(y,x,z);
        }
        for(register int i = 1;i <= w;++ i)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,-z);
        }
        if(SPFA() == false)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/acioi/p/11695060.html