루오 구 P2850 [USACO06DEC] 문제에 웜홀 웜홀 용액

P2850 [USACO06DEC] 웜홀 웜홀

제목 설명

그의 많은 농장을 탐험하는 동안, 농부 존은 놀라운 웜홀의 번호를 발견했다. 웜홀은 당신이 웜홀을 입력하기 전에하는 시간에 목적지에 당신을 제공하는 단방향 경로이기 때문에 매우 독특한입니다! 농장 FJ의 각 웜홀 (200 ≤ W ≤ 1) N (500 ≤ N ≤ 1) 편리 1..N, M (≤ 2500 1 ≤ M) 경로 번호 필드 및 W를 포함한다.

일부 필드에서 시작 어떤 경로와 웜홀을 통과하고, 그의 초기 출발 전에 시작 필드에 시간을 반환 : FJ는 열렬한 시간 여행 팬이다, 그는 다음을 수행하고자합니다. 아마도 그는 자신을 :) 만날 수있을 것입니다.

FJ이 가능 여부를 알 수 있도록 여부를 위해, 그는 자신의 농장의 F (1 ≤ F ≤ 5)에 전체지도와 함께 당신을 제공 할 것입니다. 어떤 경로를 여행하는 이상 10,000 초 정도 걸릴 것 더 웜홀은 10,000 개 이상의 초 시간을 거슬러 FJ을 가져올 수 없습니다.

자신의 농장에서 요한은 많은 방황 웜홀에서 발견. 웜홀은 매우 이상한 방향 가장자리로 간주하고, (당신이 웜홀 상대를 입력하기 전에) 당신이 과거의 시간으로 돌아갈 수 있습니다 할 수 있습니다. 각 팜 N (참조 부호 1..N) 차단하는 W에 연결되어 M 존 보도 (방향성 에지)을 갖고, 웜홀있다. 1 <= <= 200 W N <= 500,1 <= M <= 2500,1 <=. 이제 존 (출발 시간 전) 과거로 돌아가려면이 웜홀을 사용하고 싶습니다, 당신은 그것을 할 말해. 존 F (1 <= F <= 5)지도 농장를 제공합니다. 경로는 당신에게 시간을 더 이상 10,000 초 이상 비용을 부담해야하고, 확실히 다시 더 웜홀은 10,000 개 이상의 초 전 다시 얻을 수 있도록 없습니다.

입력 형식

행 1 : 단일 정수, F. F 농장의 설명은 다음과 같습니다.

각 농장의 라인 1 : 세 개의 공간 분리 된 각각 정수 : N, M, 및 W

각 라인 팜 2..M + 1 : 세 개의 공간 분리 된 번호를 각각 설명하는 (S, E, T) : 트래버스 T 초를 필요 S와 E 사이의 양방향 경로. 두 필드는 하나 개 이상의 경로로 연결 될 수 있습니다.

라인 M + 2..M + W + 각 팜 1 : 세 개의 공간 분리 된 번호를 각각 설명하는 (S, E, T) : 뒷 T 초 여행자 이동 E에 S에서 편도 경로.

출력 형식

라인의 1..F : 각 농장의 경우, 출력 "YES"FJ 자신의 목표를 달성 할 수있는 경우, "NO"그렇지 않으면 출력 (따옴표 포함되지 않습니다).

샘플 입출력

입력 # 1

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

출력 # 1

NO
YES

설명 / 팁

농장 1의 경우, FJ는 시간을 거슬러 여행 할 수 없습니다.

농장 2의 경우, FJ는 그가 떠나기 전에 자신의 시작 위치에 다시 1 초에 도착,주기 1 -> 2 -> 3 -> 1 시간을 거슬러 여행 할 수 있습니다. 그는이를 위해주기에 어디에서 시작할 수 있습니다.

[생각]

SFPA의 몰수 링은
물 링 SPFA 보드의 제목을 상실입니다

[분석] 표제

위로의 농지 웜홀 위의 어떠한 방식으로 소비되는 시간
시간 이상 도로에 반환하는 웜홀이되기 전에
얻을 수있는 시간
이되기 전에 소요되는 시간이 줄어 듭니다
소비만큼 부정적이 될 수있는 시간을
출발 시간에 돌아은 룸
마이너스가 될 수
부정적인 링의 무게
부정적인 링입니다
만 반지는 음수가 될 수를 결정 할 필요가 없도록

[SPFA의 몰수 링]

보드
알몸 보드 질문의
세부 설명 참조
여기

[전체 코드]

#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;
}

추천

출처www.cnblogs.com/acioi/p/11695060.html