POJ - 3259 Bellman_Ford || SPFA

While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination at a time that is BEFORE you entered the wormhole! Each of FJ's farms comprises N (1 ≤ N ≤ 500) fields conveniently numbered 1..NM (1 ≤ M≤ 2500) paths, and W (1 ≤ W ≤ 200) wormholes.

As FJ is an avid time-traveling fan, he wants to do the following: start at some field, travel through some paths and wormholes, and return to the starting field a time before his initial departure. Perhaps he will be able to meet himself :) .

To help FJ find out whether this is possible or not, he will supply you with complete maps to F (1 ≤ F ≤ 5) of his farms. No paths will take longer than 10,000 seconds to travel and no wormhole can bring FJ back in time by more than 10,000 seconds.

Input

Line 1: A single integer, FF farm descriptions follow. 
Line 1 of each farm: Three space-separated integers respectively: NM, and W 
Lines 2.. M+1 of each farm: Three space-separated numbers ( SET) that describe, respectively: a bidirectional path between S and E that requires T seconds to traverse. Two fields might be connected by more than one path. 
Lines M+2.. MW+1 of each farm: Three space-separated numbers ( SET) that describe, respectively: A one way path from S to E that also moves the traveler backT seconds.

Output

Lines 1.. F: For each farm, output "YES" if FJ can achieve his goal, otherwise output "NO" (do not include the quotes).

Sample Input

2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8

利用bellman_ford判断是否存在负权回路
#include <iostream>
#define MAX 505
#define INTMAX 10005
using namespace std;

struct E
{
    int b,e,t;
};
E edge[INTMAX];
int dis[MAX];

int N,M,W,count;

bool Bellman_Ford()
{
    for(int i=1;i <= N;i++)
        dis[i]=INTMAX;
    dis[1]=0;
    int flag;

    for(int i=1;i <= N-1;i++)//最多循环N-1次就可以全部更新完
    {
        flag=0;
        for(int j=0;j<count;j++)
        {
            if(dis[edge[j].e]>dis[edge[j].b]+edge[j].t)
            {
                dis[edge[j].e]=dis[edge[j].b]+edge[j].t;
                flag=1;
            }
        }
        if(!flag)//如果没有更新了,就跳出。
            break;
    }
    for(int j=0;j < count; j++)
    {
        if(dis[edge[j].e]>dis[edge[j].b]+edge[j].t)//有负权回路,没法更新完
            return true;
    }
    return false;
}

int main()
{
    int F;
    cin >> F;
    while(F--)
    {
        count=0;
        cin >> N >> M >> W;
        int b,e,t;
        while(M--)
        {
            cin >> b >> e >> t;
            edge[count].b=b;
            edge[count].e=e;
            edge[count].t=t;
            count++;
            edge[count].e=b;
            edge[count].b=e;
            edge[count].t=t;
            count++;
        }
        while(W--)
        {
            cin >> b >> e >> t;
            edge[count].b=b;
            edge[count].e=e;
            edge[count].t=-t;
            count++;
        }
        if(Bellman_Ford())
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

  

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;

const int MAXP = 6005;
const int MAXF = 505;
const int INT = 9999999;

struct Node
{
    int to,w,next;
};
Node Edge[MAXP];
int dis[MAXF],head[MAXF],times[MAXF],in[MAXF];
int N,M,W;

int cnt;
void add(int from,int to,int w)
{
    Edge[cnt].to=to;
    Edge[cnt].w=w;
    Edge[cnt].next=head[from];//head相当于头指针,cnt相当于新建节点,将cnt节点的下一个附为现在的头结点,即将cnt插到链表最后。
    head[from]=cnt++;//头结点变为cnt节点。
}
bool SPFA()
{
    queue<int> que;
    
    memset(times,0,sizeof(times));
    memset(in,0,sizeof(in));
    for(int i=1;i<=N;i++)
        dis[i]=INT;
        
    dis[1]=0,in[1]=1,times[1]=1;
    que.push(1);
    
    while(!que.empty())
    {
        int cur = que.front();
        que.pop();
        in[cur]=0;
        
        if(times[cur]==N)
            return true;
        for(int i=head[cur]//找到以cur对应的头结点;i!=-1//为空节点跳出;i=Edge[i].next//节点后移)
        {
            int id=Edge[i].to;
            if(dis[cur]+Edge[i].w<dis[id])
            {
                dis[id]=dis[cur]+Edge[i].w;
                if(!in[id])
                {
                    times[id]++;
                    in[id] = 1;
                    que.push(id);
                }
            }
        }
    }
    return false;
}
int main()
{
    int F,from,to,w;
    cin >> F;
    while(F--)
    {   
        memset(head,-1,sizeof(head));
        cin>>N>>M>>W;
        cnt = 0;
        for(int i=0;i<M;i++)
        {
            cin>>from>>to>>w;
            add(from,to,w);
            add(to,from,w);
        }
        for(int i=0;i<W;i++)
        {
            cin >> from>>to>>w;
            add(from,to,-w);
        }
        if(SPFA())
            cout << "YES\n";
        else
            cout << "NO\n";
    }
    return 0;
}

  

posted @ 2017-02-17 17:56  呆毛王王负剑  阅读(57)  评论(0)    收藏  举报