传送门:POJ3169
题意:有N头牛按编号顺序排在一条直线上(一个位置可以有多头牛),两两喜欢的牛之间距离不能超过d,两两讨厌的牛之间距离不能小于d,求1号牛和n号牛之间的最大距离。
纪念我的差分约束第一题。
因为此题第一次了解差分约束,个人强烈非常特别必须推荐我学习差分约束的博客:写的真是太好了!
感觉就算你没有最短路的基础这篇文章也能给你介绍明白差分约束是啥。
回到题上来,学会差分约束以后就明白了这其实就是个裸题啊,就差直接给说不等式了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define MAXN 10005
#define inf 0x3f3f3f3f
using namespace std;
int n,m;//点数,边数
struct node{
int v,w,next;
}mp[MAXN*100];
int pre[MAXN],dis[MAXN];
int cnt=0;
void init()
{
cnt=0;
memset(pre,-1,sizeof(pre));
}
void add(int u,int v,int w)
{
mp[cnt].v=v;
mp[cnt].w=w;
mp[cnt].next=pre[u];
pre[u]=cnt++;
}
void spfa(int s,node *ed,int *fa,int *d)//起点、边邻接表、dis数组
{
queue<int>q;
int book[MAXN];
int cnt[MAXN];
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++)//我这里是把点从1开始编号来初始化的
d[i]=inf;
memset(book,0,sizeof(book));
while(!q.empty())
q.pop();
d[s]=0;
book[s]=1;
cnt[s]++;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
book[u]=0;
for(int i=fa[u];i!=-1;i=ed[i].next)
{
int v=ed[i].v,w=ed[i].w;
if(d[v]>d[u]+w)
{
d[v]=d[u]+w;
if(!book[v])
{
q.push(v);
cnt[v]++;
book[v]=1;
if(cnt[v]>=n)
{
printf("-1\n");
return ;
}
}
}
}
}
if(d[n]>=inf)
printf("-2\n");
else
printf("%d\n",d[n]);
}
int main()
{
int m1,m2;
while(~scanf("%d%d%d",&n,&m1,&m2))
{
init();
int a,b,c;
for(int i=0;i<m1;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);//注意边的方向
}
for(int i=0;i<m2;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(b,a,-c);
}
spfa(1,mp,pre,dis);
}
return 0;
}