BZOJ 1731 [Usaco2005 dec]Layout 排队布局
2017.09.11
2017.09.11
给你一堆牛,它们站在数轴上,可能重合,还有一堆关系,形如(X,Y,Z)表示X和Y的距离不小于/不大于Z。问N号牛最远位置。
差分约束系统,直接根据$dis_y \leq dis_x+val_i$的定理建图跑最短路即可。
注意差分约束系统想跑啥跑啥不是必须最长路/最短路!只要建图方式和跑法匹配就可以……
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,ml,md,inx,iny,inz,dis[1010];
int to[40010],nex[40010],val[40010],head[1010],tot,cnt[1010];
bool inq[1010];
queue<int>q;
void addedge(int tx,int ty,int tz) {to[++tot]=ty,nex[tot]=head[tx],head[tx]=tot,val[tot]=tz;}
bool spfa()
{
memset(dis,0x3f,sizeof dis);
dis[1]=0;
inq[1]=true;
cnt[1]=1;
q.push(1);
while(!q.empty())
{
int tmp=q.front();
q.pop();
inq[tmp]=false;
for(int i=head[tmp];i;i=nex[i])
if(dis[to[i]]>dis[tmp]+val[i])
{
dis[to[i]]=dis[tmp]+val[i];
if(!inq[to[i]])
{
inq[to[i]]=true;
cnt[to[i]]++;
if(cnt[to[i]]>=n) return false;
//printf("%d %d %d\n",tmp,to[i],dis[to[i]]);
q.push(to[i]);
}
}
}
return true;
}
int main()
{
scanf("%d%d%d",&n,&ml,&md);
for(int i=1;i<=n;++i) addedge(i+1,i,0);
for(int i=1;i<=ml;++i) scanf("%d%d%d",&inx,&iny,&inz),addedge(inx,iny,inz);
for(int i=1;i<=md;++i) scanf("%d%d%d",&inx,&iny,&inz),addedge(iny,inx,-inz);
if(!spfa()) dis[n]=-1;
if(dis[n]==0x3f3f3f3f) dis[n]=-2;
printf("%d\n",dis[n]);
return 0;
}