[Usaco2005 dec]Layout 排队布局 差分约束

来源:互联网 发布:网络黑白pdf 编辑:程序博客网 时间:2024/05/13 11:45

填坑…
差分约束一般是搞一个不等式组,求xn-x1的最大最小值什么的,求最大值就转化成xa<=xb+w这样的,然后建图跑最短路(这才是最终约束的),举个例子

x1<=x0+2x2<=x0+7x3<=x0+8x2<=x1+3x3<=x2+2

那么解出来
x3<=x0+7x3<=x0+8x3<=x0+9

结果肯定是
x3<=x0+7

所以直接对于已知条件建边,大于小于可以互相转换,注意:相邻的要保证顺序。

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#define M 25000#define N 1050using namespace std;int e=1,head[N];struct edge{    int u,v,w,next;}ed[M];void add(int u,int v,int w){    ed[e].u=u; ed[e].v=v; ed[e].w=w;    ed[e].next=head[u]; head[u]=e++;}int dis[N],bo[N],tim[N],n,m1,m2;int spfa(){    queue<int> q;    memset(dis,0x3f,sizeof dis);    memset(bo,0,sizeof bo);    bo[1]=1;dis[1]=0;q.push(1);    while(!q.empty()){        int x=q.front();q.pop();bo[x]=0;        for(int i=head[x];i;i=ed[i].next){            int v=ed[i].v,w=ed[i].w;            if(dis[v]>dis[x]+w){                dis[v]=dis[x]+w;                if(!bo[v]){                    bo[v]=1;                    q.push(v);                    tim[v]++;                    if(tim[v]>n)return -1;                }            }        }    }    if(dis[n]==dis[0])return -2;    return dis[n];}int main(){    freopen("layout.in","r",stdin);    freopen("layout.out","w",stdout);    scanf("%d%d%d",&n,&m1,&m2);    int u,v,w;    for(int i=1;i<=m1;i++){        scanf("%d%d%d",&u,&v,&w);        if(u>v)swap(u,v);        add(u,v,w);    }    for(int i=1;i<=m2;i++){        scanf("%d%d%d",&u,&v,&w);        if(u>v)swap(u,v);        add(v,u,-w);    }    for(int i=1;i<n;i++)add(i+1,i,0);    printf("%d\n",spfa());    return 0;}
原创粉丝点击