zoukankan      html  css  js  c++  java
  • P7515-[省选联考 2021A卷]矩阵游戏【差分约束】

    正题

    题目链接:https://www.luogu.com.cn/problem/P7515


    题目大意

    有一个(n*m)的矩形(A),然后给出一个((n-1)*(m-1))的矩形(B)满足

    [B_{i,j}=A_{i,j}+A_{i+1,j}+A_{i,j+1}+A_{i+1,j+1} ]

    求能否构造合法矩形(A)使得(0leq a_{i,j}leq 10^6)

    (1leq Tleq 10,1leq n,mleq 300,0leq b_{i,j}leq 4 imes 10^6)


    解题思路

    如果不考虑(a_{i,j})的限制显然很容易构造一个方案。

    然后要考虑怎么调整到满足限制,不难发现我们每行/列进行(+1/-1/+1/-1...)操作不会改变(b)数组上的值,所以我们设(c_i)表示第(i)行进行了多少次,第(j)行进行了多少次,那么有

    [0leq a_{i,j}±c_i±d_jleq 10^6 ]

    如果我们控制使得每个位置的(c_i)(d_j)的符号不同那么就可以进行差分约束了。


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define ll long long
    using namespace std;
    const ll N=610;
    struct node{
    	ll to,next,w;
    }a[N*N];
    ll T,n,m,b[N][N],c[N][N];
    ll tot,cnt[N],ls[N],f[N];
    bool v[N];deque<int> q;
    void addl(ll x,ll y,ll w){
    	a[++tot].to=y;
    	a[tot].next=ls[x];
    	ls[x]=tot;a[tot].w=w;
    	return;
    }
    bool SPFA(){
    	memset(f,0x3f,sizeof(f));
    	memset(cnt,0,sizeof(cnt));
    	q.push_back(1);v[1]=cnt[1]=1;f[1]=0;
    	while(!q.empty()){
    		ll x=q.front();v[x]=0;q.pop_front();
    		for(ll i=ls[x];i;i=a[i].next){
    			ll y=a[i].to;
    			if(f[x]+a[i].w<f[y]){
    				f[y]=f[x]+a[i].w;
    				cnt[y]=cnt[x]+1;
    				if(cnt[y]>=n+m&&a[i].w<0)return 1;
    				if(!v[y]){
    					v[y]=1;
    					if(!q.empty()&&f[y]<f[q.front()])q.push_front(y);
    					else q.push_back(y);
    				}
    			}
    		}
    	}
    	return 0;
    }
    signed main()
    {
    	scanf("%lld",&T);
    	while(T--){
    		memset(ls,0,sizeof(ls));tot=0;
    		scanf("%lld%lld",&n,&m);
    		for(ll i=1;i<n;i++)
    			for(ll j=1;j<m;j++)
    				scanf("%lld",&b[i][j]);
    		memset(c,0,sizeof(c));
    		for(ll i=1;i<=m;i++)c[1][i]=0;
    		for(ll i=2;i<=n;i++){
    			c[i][1]=0;
    			for(ll j=2;j<=m;j++)
    				c[i][j]=b[i-1][j-1]-c[i-1][j-1]-c[i-1][j]-c[i][j-1];
    		}
    		for(ll i=1;i<=n;i++)
    			for(ll j=1;j<=m;j++){
    				if((i+j)&1)addl(i,j+n,c[i][j]),addl(j+n,i,1e6-c[i][j]);
    				else addl(j+n,i,c[i][j]),addl(i,j+n,1e6-c[i][j]);
    			}
    		if(!SPFA()){
    			puts("YES");
    			for(ll i=1;i<=n;i++,putchar('
    '))
    				for(ll j=1;j<=m;j++){
    					if((i+j)&1)c[i][j]=c[i][j]+f[i]-f[j+n];
    					else c[i][j]=c[i][j]-f[i]+f[j+n];
    					printf("%lld ",c[i][j]);
    				}
    		}
    		else puts("NO");
    	}
    	return 0;
    }
    
  • 相关阅读:
    hbase2.x错误记录之 disable表卡住
    hbase2.x 错误记录之 procedure is still running
    yarn timelineserver v2 配置
    Linux 系统出现大量的CLOSE_WAIT
    hbase 2.x 异常记录之 hbase shell不能分配内存
    spark 访问 hive,不能获取到数据信息
    hive 由于distcp导致执行sql慢
    Hbase 安装部署
    MooseFS安装部署
    hbase2.x 单节点启动,master挂掉
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/15018404.html
Copyright © 2011-2022 走看看