poj 3259 Wormholes

bellman算法

John的农场里field块地,path条路连接两块地,hole个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。我们的任务是知道会不会在从某块地出发后又回来,看到了离开之前的自己。

--------------------------------------------------------------------
#include <iostream>
#include <math.h>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define MAXN 520
#define MAXM 6000
#define INF 0Xffffff
using namespace std ;
struct node
{
    int u, v, w;
} edge[MAXM];
int T, n, m, l,  u, v, w;
int dis[MAXN], ans;
int bellman()
{
    for(int i=0; i<n; i++)
        dis[i] = INF;
        ///可以写成fill(dis,did+n,INF);
    dis[1] = 0;

    for(int i=0; i<n; i++)
    {
        int flag = 0;
        for(int j=0; j<ans; j++)
        {
            if(dis[edge[j].u]>dis[edge[j].v]+edge[j].w)///松弛
            {
                dis[edge[j].u]=dis[edge[j].v]+edge[j].w;
                flag = 1;
            }
        }
        if(!flag)
            break;
        ///因为对于V个点 你最多需要进行|V|-1次外循环,如果有负环它会一直进行下去,
        ///但是只要进行到第V次的时候就说明存在负环了
        if(i==n-1)///如果存在负边
            return 1;
    }
    return 0;


}
void add(int u,int v,int w)
{
    edge[ans].u = u;
    edge[ans].v = v;
    edge[ans].w = w;
    ans++;
}
int main()
{
    scanf("%d", &T);
    while(T--)
    {
        ans = 0;
        scanf("%d %d %d", &n, &m, &l);
        for(int i=0; i<m; i++)
        {
            scanf("%d %d %d", &u, &v, &w);
            add(u, v, w);
            add(v, u, w);
        }
        for(int i=0; i<l; i++)
        {
            scanf("%d %d %d", &u, &v, &w);
            add(u, v, -w);
        }
        if(!bellman()) printf("NO\n");
        else printf("YES\n");
    }

    return 0;
}

 

 
posted @ 2016-07-22 15:34  biu~biu~biu~  阅读(166)  评论(0编辑  收藏  举报