• # 差分约束系统


    差分约束系统


    水题(bzoj 1731)

    • 裸差分约束,n头牛【1,n】,(ml条这样的信息)对于两头有好感的牛距离不超过w,(md条这样的信息)对于两头有反感的牛距离至少w,且多头牛可以共享一个点,求最后一头牛和第一头牛距离最大是多少

    • 按要求建图,使用bellman或者spfa

    /*
    4 2 1
    1 3 10
    2 4 20
    2 3 3
    
    Sample Output
    27
    四只牛分别在0,7,10,27.
    
    */
    #include <bits/stdc++.h>
    using namespace std; 
    struct edge{
    	int from,cost,to;
    }e[100000];
    int k=0; 
    void build(int x,int y,int w){
    	//e[k].from=x,e[k].to=y,e[k].cost=w;
    	e[k]=edge{x,w,y};
    	k++;
    }
    int d[1005];
    int n;
    const int inf=0x7f7f7f7f; 
    bool bellman(int s){
    	memset(d,0x7f,sizeof(d));
    	d[s]=0;
    	bool update=0;
    	
    	for(int i=1;i<=n;i++){
    		update=0;
    		
    		for(int j=0;j<k;j++){
    			edge& es=e[j];
    			if(es.from!=inf&&d[es.from]+es.cost<d[es.to]){
    				d[es.to]=d[es.from]+es.cost;
    				update=1;
    				if(i==n)return 0;
    			}
    		}
    		if(!update)return 1;
    	}
    	return 1;
    } 
    int main(){
    	int ml,md;
    	scanf("%d %d %d",&n,&ml,&md);
    	int x,y,w;
    	while(ml--){
    		scanf("%d %d %d",&x,&y,&w);//y-x<=w;建有向边x->y,
    		build(x,y,w);   
    	}
    	while(md--){
    		scanf("%d %d %d",&x,&y,&w);//y-x>=w;x-y<=(-w)
    		build(y,x,-w);
    	}
    	for(int i=2;i<n;i++)build(i,i-1,0);//多头牛共享一个点,建0边
    	
    	if(!bellman(1)){
    		printf("%d",-1);
    	}
    	else{
    		if(d[n]==inf)printf("%d",-2);
    		else {
    			for(int i=1;i<=n;i++){
    				printf("%d ",d[i]);//打印可行解,题目答案即为d[n];
    			}                      //这里没有题目要求输出
    		}
    	}
    	return 0;
    }
    

    最短路算法

    • 差分约束系统一般使用bellman和spfa求最短路,也可以用来求最长路径,只需将松弛操作从(<)改成(>)

    差分约束系统

    • 条件:每个不等式只含两个变量,且系数为1和-1.

    • 不等式建边:a-b<=c(一定要小于等于),a<=b+c,to<=from+cost,建立b->a的有向边

    • 最大值最小值的理解:差分约束系统是将不等式合并成$$不等式约束下求首位距离最大值a-b<=c1a-b<=c2a-b<=c3......max(a-b)=min(c1,c2,...)相当于最短路径$$---------------------------------------------------------------------------$$不等式约束下求首位距离最小值a-b>=c1a-b>=c2a-b>=c3......min(a-b)=max(c1,c2,...)相当于最长路径$$,

    • 不等式标准化:(此处求两个点距离的最大值,如果求最小值则转化为(>=)求最长路径)

    a-b>=c  ->   b-a<=-c;
    a-b<c   ->   a-b<=c-1;
    a-b>c   ->   b-a<-c   ->   b-a<=-c-1;
    a-b=c   ->   a-b<=c&&a-b>=c
    
    • 可行解:最大值(最小值):有负(正)环时距离可以无限小(大),不可达时(两个点之间没有约束关系)距离无限大(小),有解的情况下d[i]为每个点对应的位置(一组可行解)

    差分约束详解及金典模型

    • 线性约束
    • 区间约束的(d[i]表示(0,i)区间)
    • 位置条件约束(二分+差分约束)

    参考博客感谢博主

  • 相关阅读:
    adb shell am force-stop <package>
    推荐一个代码生成工具:freemarker
    子控件跟着父控件变色
    sqlite支持的数据库类型
    android 资源文件
    一个手机基础信息的获取代码
    二维码的开源项目
    在点击HOME键时, 在点击icon回到原来的应用。
    Wireshark "The NPF driver isn’t running…"
    .atomic vs volatile
  • 原文地址:https://www.cnblogs.com/sstealer/p/11681167.html
Copyright © 2020-2023  润新知