POJ 3259-Wormholes

http://poj.org/problem?id=3259
  题意大致是N个点, M条正常的边(双向)边权为正,W个虫洞,边权为负,想要

我们判断回路中是否存在一个负圈。学习了bellman-ford算法来求负环,松弛结束后判断是否

存在最短路,不存在则有负环。

#include <stdio.h>

#include <string.h>

#include <stdlib.h>



const int maxn = 1 << 9, inf = 0x3f3f3f3f;

int dist[maxn];

int N, M, W, es;



struct Edge

{

    int u, v, w;

}e[maxn * maxn];



void addedge(int u, int v, int w)

{

    e[es].u = u, e[es].v = v, e[es ++].w = w;

}



void readgraph()

{

    int u, v, w;

    es = 0;

    scanf("%d%d%d", &N, &M, &W);

    for(int i = 0; i < M; i ++)

    {

        scanf("%d%d%d", &u, &v, &w);

        addedge(u, v, w);

        addedge(v, u, w);

    }

    for(int i = 0; i < W; i ++)

    {

        scanf("%d%d%d", &u, &v, &w);

        addedge(u, v, -w);

    }

}



void relax(int es)

{

    int u = e[es].u, v = e[es].v, w = e[es].w;

    if(dist[v] > dist[u] + w)

        dist[v] = dist[u] + w;

}



bool bellman(int src)

{

    for(int i = 1; i < N; i ++)

        dist[i] = inf;

    dist[src] = 0;

    for(int i = 0; i < N - 1; i ++)

    {

        for(int j = 0; j < es; j ++)

        {

            relax(j);

        }

    }

    for(int i = 0; i < es; i ++)

    {

        if(dist[e[i].v] > dist[e[i].u] + e[i].w)

            return false;

    }

    return true;

}



int main()

{

    int T;

    scanf("%d", &T);

    while(T --)

    {

        readgraph();

        if(!bellman(0))

            printf("YES\n");

        else

            printf("NO\n");

    }

    return 0;

}

 

 

下面就是这个算法的过程: 

Bellman-Ford(G,w,s) :boolean //图G ,边集 函数 w ,s为源点

 

  1 for each vertex v ∈ V(G) do //初始化 1阶段

 

  2 d[v] ←+∞

 

  3 d[s] ←0; //1阶段结束

 

  4 for i=1 to |v|-1 do //2阶段开始,双重循环。

 

  5 for each edge(u,v) ∈E(G) do //边集数组要用到,穷举每条边。

 

  6 If d[v]> d[u]+ w(u,v) then //松弛判断

 

  7 d[v]=d[u]+w(u,v) //松弛操作 2阶段结束

 

  8 for each edge(u,v) ∈E(G) do

 

  9 If d[v]> d[u]+ w(u,v) then

 

  10 Exit false

 

  11 Exit true

你可能感兴趣的:(orm)