您的位置:首页 > 其它

poj3259 Wormholes --- bellman/spfa判负环

2014-06-26 11:13 190 查看
输入n,m,w

表示点的个数,然后输入m条双向边,权值为正,再输入w条双向边,权值为负。

问图中是否有负环。

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
#define ll __int64
#define mod 1000000007

using namespace std;

struct node
{
    int v,w,next;
}e[5300];

int head[550],h,d[550],inq[550],outq[550],n,m,w;

void init()
{
    memset(head,-1,sizeof head);
    h=0;
}

void addedge(int a,int b,int c)
{
    e[h].v=b;
    e[h].w=c;
    e[h].next=head[a];
    head[a]=h++;
}

int spfa(int st)
{
    memset(d,0x3f,sizeof d);
    memset(inq,0,sizeof inq);
    memset(outq,0,sizeof outq);
    d[st]=0;inq[st]=1;
    queue<int> q;
    q.push(st);
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        inq[x]=0;
        outq[x]++;
        if(outq[x]>n) return 0;//存在负环
        for(int i=head[x];i!=-1;i=e[i].next)
        {
            if(d[e[i].v]>d[x]+e[i].w)
            {
                d[e[i].v]=d[x]+e[i].w;
                if(!inq[e[i].v])
                {
                    inq[e[i].v]=1;
                    q.push(e[i].v);
                }
            }
        }
    }
    return 1;
}

int bellman(int st)
{
    int i,j,k;
    memset(d,0x3f,sizeof d);
    d[st]=0;
    for(i=0;i<n-1;i++)//n-1次松弛操作
    {
        for(j=1;j<=n;j++)//枚举每条边//注意边的编号
        {
            if(d[j]==inf) continue;
            for(k=head[j];k!=-1;k=e[k].next)
            {
                if(e[k].w!=inf&&d[e[k].v]>d[j]+e[k].w)
                    d[e[k].v]=d[j]+e[k].w;
            }
        }
    }
    for(j=0;j<n;j++)
    {
        if(d[j]==inf) continue;
        for(k=head[j];k!=-1;k=e[k].next)
        {
            if(e[k].w!=inf&&d[e[k].v]>d[j]+e[k].w)
                return 0;
        }
    }
    return 1;
}

int main()
{
    int T,a,b,c;
    scanf("%d",&T);
    while(T--)
    {
        init();
        scanf("%d%d%d",&n,&m,&w);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            addedge(a,b,c);
            addedge(b,a,c);
        }
        for(int i=0;i<w;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            addedge(a,b,-c);
        }
        int ans=spfa(1);
        if(!ans)
            printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: