POJ 3169

//题目类型:典型的差分约束(Bellman-Ford算法实现)
差分约束的讲解见《算法导论》
假设X[i]表示横坐标,对于 a b d 需要满足:
 1)如果是喜欢关系,X[b] - X[a] <= d,于是加一条 a 到 b 权为 d的边;
 2) 如果是讨厌关系,X[b] - X[a] >= d,即X[a]-X[b]<=-d,于是加一条 b 到 a 权为 -d的边;
有负环输出 -1,无穷大输出-2,其他输出 dist[n].
#include <iostream>
//#include <conio.h>
using namespace std;
int n,ml,md;
typedef struct edge
{
   int v;//起点
   int u;//终点
   int w;
}edge;
edge edges[200004];
int d[1004];
int maxData = 1000000000;       //此处要特别注意,bellman-ford算法中不要使用0x7fffffff,为此wa了n次
int edgenum;
int BellmanFord(int s)
{
    int i,j;
    bool flag = false;
    for(i=1;i<n+1;++i)
    {
        d[i] = maxData;
    }
    d[s]=0;
    for(i=1;i<n;++i)
    {
        flag = false;
        for(j=0;j<edgenum;++j)
        {
            if(d[edges[j].u]>d[edges[j].v]+edges[j].w)
            {
                flag =true;
                d[edges[j].u]=d[edges[j].v]+edges[j].w;
            }
        }
        if(!flag)
           break;
    }
    for(i=0;i<edgenum;++i)
    {
        if(d[edges[i].v]<maxData && d[edges[i].u]>d[edges[i].v]+edges[i].w)
        {
             return -1;
        }
    }
    if(d[n]==maxData)
        return -2;
    else
        return d[n];
}
int main()
{
    //freopen("1.txt","r",stdin);
    int start,end,w;
    int i,j;
    while(cin>>n>>ml>>md)
    {   
         edgenum=0;
         for(i=0;i<ml;++i)
         {
             cin>>start>>end>>w;
             edges[edgenum].v = start;
             edges[edgenum].u = end;
             edges[edgenum].w = w;
             edgenum++;
         } 
         for(i=0;i<md;++i)
         {
             cin>>start>>end>>w;
             edges[edgenum].v = end;
             edges[edgenum].u = start;
             edges[edgenum].w = -w;
             edgenum++;           
         }     
         int result= BellmanFord(1);
         cout<<result<<endl; 
    }
    //getch();
    return 0;
}

 

你可能感兴趣的:(poj)