USACO 虫洞

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


#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值