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;
}