• 差分约束


    差分约束不是差分

    题目难易不安顺序,肾选

    差分约束就是一些不等式组
    a[i]-a[j]>=k1
    a[i]-a[j]<=k2
    差分约束系统就是一些不等式的组,而我们的目标是通过给定的约束不等式组求出最大值或者最小值或者差分约束系统是否有解。
    这个就可以转化为图论求解

    T1 poj 3169

    题目

    /*
    不等式 1
    b1-a1>=x
    b2-a2<=x
    求最大值
    全部化为<=
    b2-a2<=x
    a1-b1<=-x
    
    不等式2 
    xi-x(i-1)>=0 -> x(i-1)-xi<=0
    
    S=1
    跑最短路 
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    //#define int long long
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int maxm=20007;
    const int maxn=1007;
    int n,ml,md;
    int dis[maxn];
    int ru[maxn],vis[maxn];
    struct edge {
    	int v,q,nxt;
    }e[maxm];
    int head[maxm],tot;
    void add_edge(int u,int v,int q) {
    	//cout<<u<<" "<<v<<" "<<q<<"
    ";
    	e[++tot].v=v;
    	e[tot].q=q;
    	e[tot].nxt=head[u];
    	head[u]=tot;
    }
    void zzdsr(int u,int v,int q,int pd) {//1为<= 0为>= 
    	!pd ? add_edge(u,v,q):add_edge(v,u,-q);
    }
    void spfa() {
    	memset(dis,0x3f,sizeof(dis));
    	queue<int> q;
    	q.push(1);
    	dis[1]=0;
    	while(!q.empty()) {
    		int u=q.front();
    		q.pop();
    		vis[u]=0;
    		for(int i=head[u];i;i=e[i].nxt) {
    			//printf("%d -> %d
    ",u,e[i].v);
    			int v=e[i].v;
    			if(dis[v]>dis[u]+e[i].q) {
    				dis[v]=dis[u]+e[i].q;
    				if(!vis[v]) {
    					vis[v]=1;
    				
    					//环 
    					if(ru[v]==n+1) {printf("-1");return;}
    				
    					ru[v]++;
    					q.push(v);
    				}
    			}
    		}
    	}
    	//无解 
    	if(dis[n]==inf) puts("-2");
    	//正常答案 
    	else printf("%d
    ",dis[n]);
    }
    int main()
    {
    	//freopen("a.in","r",stdin);
    	//输入建边 
    	scanf("%d%d%d",&n,&ml,&md);
    	for(int i=1;i<=ml;++i) {
    		int a,b,c;
    		scanf("%d%d%d",&a,&b,&c);
    		a=min(a,b);
    		b=max(a,b);
    		zzdsr(a,b,c,0);
    	}
    	for(int i=1;i<=md;++i) {
    		int a,b,c;
    		scanf("%d%d%d",&a,&b,&c);
    		a=min(a,b);
    		b=max(a,b);
    		zzdsr(a,b,c,1);
    	}
    	
    //	xi-x(i-1)>=0 -> x(i-1)-xi<=0
    	for(int i=2;i<=n;++i)
    		zzdsr(i-1,i,0,1);
    	
    	//判断1到n 
    	spfa();
    	return 0;	
    }
    

    T2 poj1201

    题目

    /*
    求1到n的最小值
    最长路
    转化为>=
    b - (a-1) >= c
    {
    	b - (a-1) >= c
    }
    0 <= xi - x(i-1) <=1
    {
    	x(i-1) - xi >= -1	
    	xi - x(i-1) >= 0
    }
    */
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int maxn=50100;
    int n;
    int dis[maxn],vis[maxn];
    int mi=inf,ma;
    struct node {
    	int v,q,nxt;
    }e[maxn*100];
    int head[maxn*100],tot;
    void add_edge(int u,int v,int q) {
    	e[++tot].v=v;
    	e[tot].q=q;
    	e[tot].nxt=head[u];
    	head[u]=tot;
    }
    void spfa()
    {
    	for(int i=mi-1;i<=ma;++i)
    		dis[i]=-0x3f3f3f3f;
    	queue<int> q;
    	q.push(mi-1);
    	dis[mi-1]=0;
    	while(!q.empty()) {
    		int u=q.front();
    		q.pop();
    		vis[u]=0;
    		for(int i=head[u];i;i=e[i].nxt) {
    			int v=e[i].v;
    			if(dis[v]<dis[u]+e[i].q) {
    				dis[v]=dis[u]+e[i].q;
    				if(!vis[v]) {
    					vis[v]=1;
    					q.push(v);
    				}
    			}
    		}
    	}
    	printf("%d
    ",dis[ma]);
    }
    int main()
    {
    	scanf("%d",&n);
    
    	for(int i=1;i<=n;++i) {
    		int a,b,c;
    		scanf("%d%d%d",&a,&b,&c);
    		add_edge(a-1,b,c);
    		mi=min(a,mi);
    		ma=max(b,ma);
    	}
    	for(int i=mi;i<=ma;++i) {
    		add_edge(i,i-1,-1);
    	 	add_edge(i-1,i,0);
    	}
    	spfa();
    	return 0;
    }
    

    T3 POJ 1275

    POJ 1275

    #include<queue>
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int N=1000+100,K=30;
    int s[K],r[K],h[K];
    struct node
    {
        int v,nxt,w;    
    }e[N*10];
    int head[N],ejs;
    void add(int u,int v,int w) {
        e[++ejs].v=v;e[ejs].w=w;e[ejs].nxt=head[u];head[u]=ejs;
    }
    int dis[K],vis[K],in[K];
    int spfa() {
      	queue<int> q;
        memset(in,0,sizeof(in));
        memset(dis,-0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        dis[0]=0;
        q.push(0);
        while(!q.empty()) {
            int u=q.front();
            q.pop();
            vis[u]=0;
            for(int i=head[u];i!=-1;i=e[i].nxt) {
                int v=e[i].v;
                if(dis[v]<dis[u]+e[i].w) {
                    dis[v]=dis[u]+e[i].w;
                    if(!vis[v]) {
                        vis[v]=1;
                        q.push(v);
                        in[v]++;
                        if(in[v]>24) return 0;
                    }
                }
            }
        }
        return 1;
    }
    int work(int ans) {
        ejs=0;
        memset(head,-1,sizeof(head));
        for(int i=1;i<=24;++i)
            add(i,i-1,-h[i]),
            add(i-1,i,0);
        for(int i=1;i<=8;++i)
            add(i+16,i,r[i]-ans);
        for(int i=9;i<=24;++i)
            add(i-8,i,r[i]);
        add(0,24,ans);
        add(24,0,-ans);
        return spfa();
    }
    int main() {
        ios::sync_with_stdio(false);
        int T;
        cin>>T;
        while(T--) {
            memset(r,0,sizeof(r));
            memset(h,0,sizeof(h));
            for(int i=1;i<=24;++i)
                cin>>r[i];
            int m;
            cin>>m;
            for(int i=1;i<=m;++i) {
                int x;
                cin>>x;
                h[x+1]++;
            }
            int i;
            for(i=0;i<=m;++i)
                if(work(i)) break;
            if(i<=m)
            	printf("%d
    ",i);
            else
                printf("No Solution
    ");
        }
        return 0;
    }
    

    T4 POJ 2983

    题目

    /*
    mc L teacher 讲的好快啊
    类似网络流的套路
    一个个枚举GG掉了
    然后一个超级S连接每个点,q=0
    这样就没有影响了
    
    P A B X代表A站在B站北方X光年处
    V A B 代表A站在B站北方,而且距离至少为1光年
    以南为正方向
    
      B-A == X  
     =B-A >= X and B-A <= X
     =B-A >= X and A-B >= -X
    
      B-A >= 1
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    #define NO "Unreliable"
    #define YES "Reliable"
    const int inf=0x3f3f3f3f;
    const int maxn=500007;
    struct Edge {
    	int v,nxt,q;
    }e[maxn<<2];
    int head[maxn<<2],tot;
    void add_Edge(int u,int v,int q) {
    	//printf("%d -> %d q=%d
    ",u,v,q);
    	e[++tot].v=v;
    	e[tot].q=q;
    	e[tot].nxt=head[u];
    	head[u]=tot;
    }
    int n,m,dis[maxn],vis[maxn],ru[maxn];
    void spfa(int S) {
    	memset(dis,-0x3f,sizeof(dis));
    	memset(vis,0,sizeof(vis));
    	memset(ru,0,sizeof(ru));
    	queue<int> q;
    	q.push(S);
    	dis[S]=0;
    	while(!q.empty()) {
    		int u=q.front();q.pop(),vis[u]=0;
    		for(int i=head[u];i;i=e[i].nxt) {
    			int v=e[i].v;
    			if(dis[v]<dis[u]+e[i].q) {
    				dis[v]=dis[u]+e[i].q;
    				if(!vis[v]) {
    					vis[v]=1;
    					if(ru[v]>=n) {puts(NO);return;}
    					ru[v]++;
    					q.push(v);
    				}
    			}
    		}
    	}
    	puts(YES);
    }
    int main() {
    	//freopen("a.in","r",stdin);
    	while(scanf("%d%d",&n,&m)!=EOF)
    	{
    		memset(head,0,sizeof(head));
    		tot=0;
    		int a,b,x;
    		char s;
    		for(int i=1;i<=m;++i) {
    			s=getchar();
    			while(s==' ' || s=='
    ') s=getchar();
    			if(s=='P') {
    				scanf("%d%d%d",&a,&b,&x);
    				add_Edge(a,b,x);
    				add_Edge(b,a,-x);
    			}
    			else {
    				scanf("%d%d",&a,&b);
    				add_Edge(a,b,1);
    			}
    		}
    
    		//超级虚  点 0 连接每一个点,q=0
    		for(int i=1;i<=n;++i)
    			add_Edge(0,i,0);
    
    		spfa(0);
    	}
    	return 0;
    }
    

    T5 hdu 3340

    题目

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    using namespace std;
    const int maxn=121010;
    const int inf=0x3f3f3f3f;
    int cnt;
    struct node {
        int x,id;
        bool operator < (const node &b) const {
            return x<b.x;
        }
    }a[maxn];
    struct edge {
        int v,nxt,q;
    }e[maxn<<2];
    int head[maxn<<2],tot;
    void add(int u,int v,int q) {
        //printf("%d -> %d q=%d
    ",u,v,q );
        e[++tot].v=v;
        e[tot].q=q;
        e[tot].nxt=head[u];
        head[u]=tot;
    }
    int n,d,S,T;
    int dis[maxn],vis[maxn],ru[maxn];
    void spfa() {
        for(int i=0;i<=n;++i)
            dis[i]=0x7fffffff;
        memset(vis,0,sizeof(vis));
        memset(ru,0,sizeof(ru));
        queue<int> q;
        q.push(S);
        dis[S]=0;
        while(!q.empty()) {
            int u=q.front();
            q.pop();
            vis[u]=0;
            for(int i=head[u];i;i=e[i].nxt) {
                int v=e[i].v;
                if(dis[v] > dis[u]+e[i].q) {
                    dis[v]=dis[u]+e[i].q;
                    if(!vis[v]) {
                        vis[v]=1;
                        if(ru[v]>n) {puts("-1");return;}
                        ru[v]++;
                        q.push(v);
                    }
                }
            }
        }
        printf("%d
    ",dis[T]);
    }
    void solve() {
        printf("Case %d: ",++cnt);
        memset(head,0,sizeof(head));tot=0;
        scanf("%d%d",&n,&d);
        for(int i=1;i<=n;++i) {
            a[i].id=i;
            scanf("%d",&a[i].x);
        }
        sort(a+1,a+1+n);
        for(int i=1;i<n;++i)
        {
            add(i+1,i,-1);
            int u = max(a[i].id, a[i+1].id), v = min(a[i].id, a[i+1].id);  
            if (u-v > d) {puts("-1");return;}
            add(v,u,d);  
        }
        S=a[1].id,T=a[n].id;
        if(S>T) swap(S,T);
        spfa();
    }
    int main() {
        //freopen("a.in","r",stdin);
        int T;
        scanf("%d",&T);
        while(T--)
            solve();
        return 0;
    }
    
    
    
    
    /*
    一
    给定顺序的差值小于等于d
    y-x<=d
    二
    排序之后的大小关系
    高度x<y
    y-x>=1
    x-y<=-1
    
    求最大距离
    <=
    最短路
    */
    
    
  • 相关阅读:
    Firefly官方教程之DBentrust使用文档
    《烽烟OL》简介
    《暗黑世界》简介
    CrossApp简介
    内联元素于与块元素的转换 相对定位、绝对定位以及fixed定位 Z轴覆盖
    div介绍 盒子模型边框属性 CSS初始化 文字排版 边框调整 溢出
    CSS样式补充第二天
    CSS样式
    form表单以及内嵌框架标签
    html对a标签的运用以及属性,img图像标签的属性及应用
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/9657671.html
Copyright © 2020-2023  润新知