zoukankan      html  css  js  c++  java
  • 差分约束

    差分约束

    (1) 求不等式组的可行解

    步骤:

    ​ [1] 先将每个不等式 xi < = xj + ck 转换成一条从xj 走到 xi ,长度为ck的一条边 即表示为 离源点距离dist[i]<=dist[j]+ck

    ​ [2] 找一个超级源点,使得该源点一定可以遍历到所有边。

    ​ [3]从源点求一遍单源最短路

    ​ 结果1:如果存在负环,则不等式组一定无解

    ​ 结果2:如果没有负环,则dist[i]就是不等式组的一个可行解

    (2) 如何求得最大值或最小值,最值是每个变量的最值。

    结论:

    ①如果求的是最小值,则应该求最长路(在所有下界里,求最大值)//下界就是去为了求最小,最大值就是求能满足条件的下界中的最大值,所求即最小值。

    ​ 注意:如果存在正环,则无解。

    ②如果求的是最大值,则应该求最短路。(上界的最小值)。

    ​ 注意:如果存在负环,则无解。

    如果求最小值,则应该是最长路,然后把所有的符号都变为>或>=

    如果求最大值,则应该是最短路,然后把所有的符号都变为<或<=

    例题

    cWing 1169. 糖果

    链接1169. 糖果 - AcWing题库

    AC代码:

    注意:边要加上超级源点的边,所以至少开2*m + n个边,否则会wa

    #include <iostream> 
    #include <cstring>
    #include <stack>
    using namespace std;
    /*
    1 a==b  a>=b+0  b>=a+0
    2 a<b   b>=a+1
    3 a>=b  a>=b
    4 a>b   a>=b
    5 a<=b  b>=a
    并且建立一个超级源点
     x=0
     i>=x+1
     
     建边时: i > = j + s 则 add(j,i,s)   
     后面的指向前边的,长度为s 
    */
    const int N = 1e5+5,M = 5e5+10;
    typedef long long ll;
    ll h[N],e[M],ne[M],idx;
    ll w[M];
    void add(ll a,ll b,ll c){
    	e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
    }
    ll dist[N];
    bool vis[N];
    ll cnt[N];
    stack<ll> q;
    ll n,k;
    
    bool spfa(){//在这里求最长路,并且要判断有无正环 
    	memset(dist,-0x3f,sizeof dist);
    	dist[0]=0;
    	q.push(0);
    	vis[0]=true; 
    	while(q.size()){
    		ll t=q.top();
    		q.pop();
    		vis[t]=false;
    		for(ll i=h[t];i!=-1;i=ne[i]){
    			ll j=e[i];
    			if(dist[j]<w[i]+dist[t]){
    				dist[j]=w[i]+dist[t];
    				cnt[j]=cnt[t]+1;
    				if(cnt[j]>=n+1) return false; 
    				if(!vis[j]){
    					q.push(j);
    					vis[j]=true;
    				}
    			}
    		}
    	}
    	return true;
    }
    
    int main(){
    	scanf("%lld%lld",&n,&k);
    	memset(h,-1,sizeof h); 
    	ll x,a,b;
    	for(ll i=0;i<k;i++){
    		scanf("%lld%lld%lld",&x,&a,&b);
    		if(x==1) add(b,a,0),add(a,b,0);
    		else if(x==2) add(a,b,1);
    		else if(x==3) add(b,a,0);
    		else if(x==4) add(b,a,1); 
    		else add(a,b,0); 
    	} 
    	for(ll i=1;i<=n;i++) add(0,i,1);
    	if(!spfa()){
    		printf("-1
    ");
    	}else{
    		long long ans=0;
    		for(ll i=1;i<=n;i++) {
    			ans+=dist[i];	
    		}
    		printf("%lld
    ",ans);
    	}
    }
    
    
  • 相关阅读:
    iOS 发送位置消息
    集成 jpush-react-native 常见问题汇总 (iOS 篇)
    RESTful API 最佳实践
    RESTful API 设计指南
    理解RESTful架构
    PHP 调用 shell
    Laravel Model updating&updated 事件使用注意事项
    sudo 命令报 unable to resolve host 导致反应速度变慢
    Nginx设置禁止通过IP访问服务器并且只能通过指定域名访问
    Homestead can not mount nfs on macos catalina
  • 原文地址:https://www.cnblogs.com/AC673523745/p/14829713.html
Copyright © 2011-2022 走看看