您的位置:首页 > 其它

poj 3259 worm-holes spfa判断负权回路

2017-03-23 17:07 435 查看


B - Wormholes

 POJ - 3259 

如果没有负权回路,则一个点的被松弛的次数一定小于等于n-1。

所以如果某个点进出超过这个次数,则说明存在负权边,即可以沿负边一直走,

陷入死循环。。。

spfa模板+前向星。

#include<cstdio>

#include<cstring>

#include<iostream>

#include <cmath>

#include <queue>

using namespace std ;

const int inf = 0x3f3f3f3f;

const int MAXN = 10005;

bool vis[MAXN];

int Count[MAXN];

int head[MAXN];

struct node

{

    int to, next;

    int c;

} G[MAXN];

int cnt;

int dist[MAXN];

int n;

void add(int u, int v, int c)

{

    G[cnt].to=v;

    G[cnt].c=c;

    G[cnt].next=head[u];

    head[u]=cnt++;

}

bool spfa(int s)

{

    int u, v;

    queue <int> q;

    memset(vis, false, sizeof(vis));

    memset(Count, 0, sizeof(Count));

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

        dist[i]=inf;

    q.push(s),Count[s]++,vis[s]=true, dist[s]=0;

    while(!q.empty())

    {

        u = q.front();

        q.pop();

        vis[u]=0;

        for(int i=head[u]; ~i; i=G[i].next)

        {

            v=G[i].to;

            if(dist[v]>dist[u]+G[i].c)

            {

                dist[v]=dist[u]+G[i].c;

                if(!vis[v])

                {

                    vis[v]=1;

                    q.push(v);

                    Count[v]++;

                    if(Count[v]>n-1)

                        return true;

                }

            }

        }

    }

    return false;

}

int main()

{

    int t, u, v, m, c, w;

    scanf("%d", &t);

    while(t--)

    {

        scanf("%d %d %d", &n, &m, &w);

        cnt=0;

        memset(head,-1,sizeof(head));

        while(m--)

        {

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

            add(u, v, c);

            add(v, u, c);

        }

        while(w--)

        {

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

            add(u, v, -c);

        }

        if(spfa(1))

            printf("YES\n");

        else

            printf("NO\n");

    }

    return 0;

}

还有一种就是bellman-ford

#include <stdio.h>  

  

#define maxN 502  

#define maxM 2702  

#define inf 1000000000  

  

struct EDGE   

{  

    int u,v,w;  

}edge[2 * maxM];  

int dis[maxN];  

  

int N, M, W;  

int edgeNum;  

  

void Init()  

{  

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

    {  

        dis[i] = inf;  

    }  

}  

  

bool bellMan(void)  

{  

    bool flag;  

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

    {  

        flag = false;  

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

        {  

            if (dis[edge[j].v] > dis[edge[j].u] + edge[j].w)//松弛  

            {  

                dis[edge[j].v] = dis[edge[j].u] + edge[j].w;  

                flag = true;  

            }  

        }  

        if (!flag)//存在负权回路  

        {  

            break;  

        }  

    }  

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

    {  

        if(dis[edge[i].v] > dis[edge[i].u] + edge[i].w)  

            return true;  

    }  

    return false;  

}  

  

int main()  

{  

    int F;  

    scanf("%d", &F);  

    while (F --)  

    {  

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

        edgeNum = 0;  

        Init();  

        int u,v,w;  

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

        {  

            scanf("%d%d%d", &u, &v, &w);//正权双向  

            edge[edgeNum].u = u;  

            edge[edgeNum].v = v;  

            edge[edgeNum].w = w;  

            edgeNum ++;  

            edge[edgeNum].u = v;  

            edge[edgeNum].v = u;  

            edge[edgeNum].w = w;  

            edgeNum ++;  

        }  

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

        {  

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

            edge[edgeNum].u = u;  

            edge[edgeNum].v = v;  

            edge[edgeNum].w = -w;//负权  

            edgeNum ++;  

        }  

        if(bellMan())    

            printf("YES\n");  

        else    

            printf("NO\n");  

  

    }  

    return 0;  

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: