USACO 虫洞

USACO 虫洞
2017年6月21日
Bellman-Ford 算法


#include
#include
#include
#include
#include
#include
#include
using namespace std;
/*
有N(1 <= N <= 500)个洞口,标号1..N;
它们之间有M (1 <= M <= 2500)条通道相连;
有W (1 <= W <=200)条时间虫洞;
INPUT
第一行:一个整数 F (1 <= F <= 5),表示共有F组数据。(多组数据测试)
每组数据:
第1行:三个整数 N  M  W
第2至M+1行:每行三个整数 (S, E, T),表示在S与E洞口之间有一个双向通道,通过需要T(0 <= T <= 10,000) 秒。
第M+2至M+W+1行:每行三个整数 (S, E, T),表示在S与E洞口之间有一个单向通道,从S到E可以回到之前T(0 <= T <= 10,000) 秒。
*/
int F;
int N, M, W;
int sr, en, ti;

struct Edges{
    int x, y, v;
}E[6000];
int ans_egs;
int V_dis[510];

inline void ReadInEgde(int m, int n, int p){
    E[++ans_egs].x = m;
    E[ans_egs].y = n;
    E[ans_egs].v = p;
}

void Putin()
{
    cin >> N >> M >> W;
    for(int i = 1; i <= M; i++){
        cin >> sr >> en >> ti;
        ReadInEgde(sr, en, ti);
        ReadInEgde(en, sr, ti);
    }
    for(int i = 1; i <= W; i++){
        cin >> sr >> en >> ti;
        ReadInEgde(sr, en, -ti);
    }
}

bool SP_BELLMANFORD()
{
    V_dis[1] = 0;   bool Rel;
    for(int k = 1; k <= N; k++)
    {
        Rel = false;
        for(int i = 1; i <= ans_egs; i++)
            if(V_dis[E[i].x] + E[i].v < V_dis[E[i].y]){
                Rel = true;
                V_dis[E[i].y] = V_dis[E[i].x] + E[i].v;
            }
        if(!Rel)    return false;
    }
    return true;
}

int main()
{
    cin >> F;
    for(int i = 1; i <= F; i++){
        memset(V_dis, 10, sizeof(V_dis));
        ans_egs = 0;
        Putin();
        bool jud = SP_BELLMANFORD();
        if(!jud)    cout << "NO" << endl;
        else        cout << "YES" << endl;
        //return 0;//DEBUGS
    }
    return 0;
}

你可能感兴趣的:(USACO 虫洞)