POJ 3259 用Bellman-Ford判断负环

来源:互联网 发布:网络博客怎么开设平台 编辑:程序博客网 时间:2024/06/06 01:49

这题的题意我没怎么看明白,看了题解我才知道到底是怎么回事。。

是判断一个图有没有负环。

第一行输入测试的样例的个数

第二行给你顶点数N,正权路个数M,负权路个数W。

剩下的M+W行是各个边的起点和终点和权值的绝对值。

稍微注意一下,题目给的是正权路是双向的而负权路是单向的,在输入时候注意一下。

接着就是用Bellman-Ford判断负环了,没有接触过的同学可以去看一下。

其实这是用了一个最短路的算法来判断最短路没有关系一个问题——图中有无负环……和最短路问题没有联系……

AC代码

#include <iostream>#include <string>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int maxn=3010;const int inf=0x3f3f3f3f;//it's not convenient for bellman-ford algorithm//to judge multiple edges if u use a structure//to restore the graph.//because it's related to edges' ID.int N,M,W;int dis[maxn];struct e{    int s,e,w;}edge[maxn];bool bellmanford(){    int r=N-1;    while(r--)    {        for(int i=1;i<=M*2+W;i++)        {            if(dis[edge[i].e]>dis[edge[i].s]+edge[i].w)                dis[edge[i].e]=dis[edge[i].s]+edge[i].w;        }    }        //the real judge if there is a negative circle.    for(int i=1;i<=M*2+W;i++)        {            if(dis[edge[i].e]>dis[edge[i].s]+edge[i].w)                return 1;        }    return 0;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        memset(dis,0,sizeof(dis));        memset(edge,0,sizeof(edge));        scanf("%d%d%d",&N,&M,&W);        int t1,t2,t3;        int i=1;        for(;i<=M*2;i+=2)//bidirectional path for positive path        {            scanf("%d%d%d",&t1,&t2,&t3);            edge[i+1].e=t1; edge[i].s=t1;            edge[i+1].s=t2; edge[i].e=t2;            edge[i+1].w=edge[i].w=t3;        }        for(;i<=M*2+W;i++)        {            scanf("%d%d%d",&t1,&t2,&t3);            edge[i].s=t1;            edge[i].e=t2;            edge[i].w=-t3;        }        bool f=bellmanford();        if(f) printf("YES");        else printf("NO");        printf("\n");    }}


原创粉丝点击