POJ 3259 Wormholes

题意:有f组测试样例,每组样例第一行 n, m, w; 有n个点, m条双向正常边, w条单向的反常边(边值为负)。求是否可以穿越时空(求负环)。

解析:spfa可以求负环,用邻接矩阵会超时,可以用邻接表或者vector。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

const int maxn = 555;
const int oo = 1e9;

int dist[maxn];
int a[6000];

struct M
{
    int x, y, z;
    int next;
}Map[6000];
int k;

void Init()
{
    memset(a, -1, sizeof(a));
    k = 0;
}

void add(int x, int y, int z)
{
    Map[k].x = x;
    Map[k].y = y;
    Map[k].z = z;
    Map[k].next = a[x];
    a[x] = k++;
}


int spfa(int x, int n)
{
    for(int i=1; i<=n; i++)
    {
        dist[i] = oo;
    }
    dist[x] = 0;
    queue<int> q;
    q.push(x);
    int s;
    while(q.size())
    {
        s = q.front();
        q.pop();

        for(int i=a[s]; i!=-1; i=Map[i].next)
        {
            M start = Map[i];
            if(dist[start.y]>dist[s]+start.z)
            {
                dist[start.y] = dist[s]+start.z;
                q.push(start.y);
            }
        }

    }
    return 0;
}

int main()
{
    int f, n, m, w;
    scanf("%d", &f);
    while(f--)
    {
        scanf("%d %d %d", &n, &m, &w);
        int s, e, t;
        Init();
        for(int i=1; i<=m; i++)
        {
            scanf("%d %d %d", &s, &e, &t);
            add(s, e, t);
            add(e, s, t);
        }
        for(int i=1; i<=w; i++)
        {
            scanf("%d %d %d", &s, &e, &t);
            add(s, e, -t);
        }

        int ans = spfa(1, n);
        if(ans)
            printf("YES
");
        else
            printf("NO
");
    }

    return 0;
}
原文地址:https://www.cnblogs.com/mengzhong/p/5352641.html