POJ-3259 Wormholes bellman

该题题意非常有意思,问是否能够时空穿梭。

这题与前面所做的POJ1860很相似,只是这里说明两点:

1.所以逇路都是双向的,洞是单向的。

2.bellman算法中,需要虚拟出一个节点,让其能够通向所有的节点(或者直接将所有点的距离都赋值为相同值)。这样就只要一次bellman算法就可以了。

代码如下:

#include <cstring>
#include <cstdlib>
#include <cstdio>
#define MAXN 6000
using namespace std;

int N, M, W, dis[505];

struct edge
{
    int a, b, t;
}e[MAXN];  // 建立边 

bool bellman()
{
    memset(dis, 0, sizeof (dis));
    for (int i = 1; i <= N+5; ++i) {
        for (int j = 0; j < M+M+W; ++j) {
            if (dis[ e[j].a ]!= 0x3f3f3f3f && dis[ e[j].a ]+e[j].t < dis[ e[j].b ]) {
                dis[ e[j].b ] = dis[ e[j].a ]+e[j].t;
            }
        }
    }
    for (int j = 0; j < M+M+W; ++j) {
        if (dis[ e[j].a ]!= 0x3f3f3f3f && dis[ e[j].a ]+e[j].t < dis[ e[j].b ]) {
            return true;
        }
    }
    return false;
}

int main()
{
    int F, flag;
    scanf("%d", &F);
    while (F--) {
        flag = 0;
        scanf("%d %d %d", &N, &M, &W);
        for (int i = 0, j = M+W; i < M; ++i, ++j) {
            scanf("%d %d %d", &e[i].a, &e[i].b, &e[i].t);
            e[j].a = e[i].b, e[j].b = e[i].a, e[j].t = e[i].t;
        }
        for (int j = M; j < M+W; ++j) {
            scanf("%d %d %d", &e[j].a, &e[j].b, &e[j].t);
            e[j].t *= -1; 
        }
        if (bellman()) {
            printf("YES\n"); 
        }
        else { 
             printf("NO\n");
        }
    }
    return 0;    
}
posted @ 2012-06-30 18:14  沐阳  阅读(223)  评论(0编辑  收藏  举报