Bzoj1731 排队布局
当排队等候喂食时,奶牛喜欢和它们的朋友站得靠近些。FJ 有 N 头奶牛,编号从 1 到 N,沿一条直线站着等候喂食。奶牛排在队伍中的顺序和它们的编号是相同的。因为奶牛相当苗条,所以可能有两头或者更多奶牛站在同一位置上。即使说,如果我们想象奶牛是站在一条数轴上的话,允许有两头或更多奶牛拥有相同的横坐标。一些奶牛相互间存有好感,它们希望两者之间的距离不超过一个给定的数 L。另一方面,一些奶牛相互间非常反感,它们希望两者间的距离不小于一个给定的数 D。
给出 ML条关于两头奶牛间有好感的描述,再给出 MD条关于两头奶牛间存有反感的描述。你的工作是:如果不存在满足要求的方案,输出 −1;如果 1 号奶牛和 N号奶牛间的距离可以任意大,输出 −2;否则,计算出在满足所有要求的情况下,1 号奶牛和 N 号奶牛间可能的最大距离。
很显然,我们对于两个要在一起的情况,相当于想这两个点之间添加一条长度相应的边,使得在没有更短路的时候可以走这条
然后对于分开的则是添加一条负权边
典型的差分约束
特别的,相邻的两个牛之间之间添加一条距离为0的边
下面给出代码:
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cstdlib> #include<string> #include<cmath> using namespace std; inline int rd(){ int x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x*f; } inline void write(int x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); return ; } int n,m1,m2; int head[100006],nxt[100006],to[100006]; int v[100006]; int total=0; void add(int x,int y,int z){ total++; to[total]=y; v[total]=z; nxt[total]=head[x]; head[x]=total; return ; } int q[100006]; int l=0,r=0; int book[100006]; int dis[100006]; int cnt[100006]; int f=0; void spfa(){ memset(dis,127,sizeof(dis)); dis[1]=0; book[1]=1; q[++r]=1; while(l<r){ int x=q[++l]; book[x]=0; for(int e=head[x];e;e=nxt[e]){ if(dis[to[e]]>dis[x]+v[e]){ dis[to[e]]=dis[x]+v[e]; cnt[x]++; if(cnt[x]==n){ f=1; return ; } if(!book[to[e]]){ book[to[e]]=1; q[++r]=to[e]; } } } } return ; } int main(){ n=rd(),m1=rd(),m2=rd(); for(int i=1;i<=m1;i++){ int x=rd(),y=rd(),z=rd(); add(x,y,z); } for(int i=1;i<=m2;i++){ int x=rd(),y=rd(),z=rd(); add(y,x,-z); } for(int i=2;i<=n;i++) add(i,i-1,0); spfa(); if(f) printf("-1"); else if(dis[n]==2139062143) printf("-2"); else write(dis[n]); return 0; }
蒟蒻总是更懂你✿✿ヽ(°▽°)ノ✿