题目:
cogs: > http://cogs.pro/cogs/problem/problem.php?pid=1117
poj: > http://poj.org/problem?id=3169
题意分析
n a b
x[i] x[j] a[k]
…
即有n个对象,a种大于关系,b种小于关系,
以下a行表示x[i]-x[j]>a[k],
接着b行表示x[i]-x[j]>a[k].
求x[1]和x[n]之间的最小距离。
思路
运用差分约束系统就可以轻松完成这个题。
把两头牛之间的最大距离转化成正边,最小距离转化成负边,
将各牛转化为点,相互连接。求1,n之间的最短路即可。
如果存在负权环即不存在任何一种可行方案输出“-1”;
如果1和n之间不存在任何限制那么则可以任意安排,输出“-2”
贴代码=.=:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 1010
#define maxe 20010
using namespace std;
int n,m,a,b,c,u,v,h,t,num,number,head[maxn],dis[maxn],cnt[maxn],team[2*maxn+5];
bool boo[maxn];
struct edges
{
int x,y,next,val;
}edge[maxe];
void add(int x,int y,int val)
{
edge[++num].x=x;
edge[num].y=y;
edge[num].val=val;
edge[num].next=head[x];
head[x]=num;
}
int main()
{
scanf("%d%d%d",&number,&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(b,a,-c);
}
memset(dis,0x3f3f3f3f,sizeof(dis));
h=0;t=1;team[1]=1;
dis[1]=0;boo[1]=1;
do
{
h=(h+1)%(maxn*2+5);
boo[team[h]]=0;
u=team[h];
for(int i=head[u];i;i=edge[i].next)
{
v=edge[i].y;
int val=edge[i].val;
if(dis[v]>dis[u]+val)
{
dis[v]=dis[u]+val;
cnt[v]++;
if(cnt[v]>number)
{
printf("-1\n");
return 0;
}
if(!boo[v])
{
boo[v]=1;
t=(t+1)%(maxn*2+5);
team[t]=v;
}
}
}
}while(t!=h);
printf("%d\n",dis[number]!=dis[0]&&dis[number]?dis[number]:-2);
}