spfa算法

poj 3259

***spfa算法结合邻接表,可以处理一些带负权值的问题,处理最短路问题***

  

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

using namespace std;
#define oo 0x3f3f3f3f
#define N 100010
int a[N];
int dist[N];
int used[N];
int vis[N];

struct node
{
    int u, v, len;
    int next;
}maps[N];

int k;
int n, m, w, t;

void Init()
{
    k=1;
    memset(a, -1, sizeof(a));
    for(int i=1; i<=n; i++)
        dist[i]=oo;
    memset(used, 0, sizeof(used));
    memset(vis, 0, sizeof(vis));
}

void add(int u, int v, int len)//处理邻接表使用的函数
{
    maps[k].u=u;
    maps[k].v=v;
    maps[k].len=len;
    maps[k].next=a[u];
    a[u]=k++;
}

int spfa()
{
    queue<int> q;
    int start=1;
    q.push(start);
    dist[1]=0;

    used[1]=1;
    vis[1]=1;
    int v;

    while(!q.empty())
    {
        start=q.front();
        vis[start]=0;
        q.pop();
        for(int i=a[start]; i!=-1; i=maps[i].next)
        {
            v=maps[i].v;
            if(dist[v]>dist[start]+maps[i].len)
            {
                dist[v]=dist[start]+maps[i].len;
                if(vis[v]==1)
                    continue;
                q.push(v);
                used[v]++;
                vis[v]=1;
                if(used[v]>=n)
                    return 1;
            }
        }
    }
    return 0;
}

int main()
{
    scanf("%d", &t);

    while(t--)
    {
        scanf("%d%d%d", &n, &m, &w);
        Init();
        int u, v, len;
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d", &u, &v, &len);
            add(u, v, len);
            add(v, u, len);
        }
        for(int i=1; i<=w; i++)
        {
            scanf("%d%d%d", &u, &v, &len);
            add(u, v, -len);
        }

        int ans=spfa();

        if(ans)
            printf("YES\n");
        else
            printf("NO\n");
    }
}

 

posted on 2016-07-10 18:25  南风丶丶  阅读(214)  评论(0编辑  收藏  举报