洛谷 P7515 [省选联考 2021 A 卷] 矩阵游戏(构造,差分约束)

Posted 尹昱钦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P7515 [省选联考 2021 A 卷] 矩阵游戏(构造,差分约束)相关的知识,希望对你有一定的参考价值。

传送门


解题思路

其实这个题部分分还是很好想的,但是考场上硬是没拿满…………
直接说正解:
假如没有对元素大小的限制,很显然可以直接设定第n行和第m列的数字为0,一定能构造出一组解。
然后考虑限制。
我们发现,对某一行或者某一列的元素进行\\(+1 \\ -1\\ +1 \\ -1 \\ +1\\ -1\\ \\cdots\\cdots\\)对答案是没有影响的
所以对于每一个点(i,j),就需要保证一个不等式的成立:
\\(0\\leqslant b[i][j]\\pm h[i]\\pm l[j]\\leqslant 10^6\\)
便于差分约束系统,我们对于行这样:
\\(\\begin{vmatrix} +1 & -1 & +1 & -1 \\\\ -1 & +1 & -1 & +1 \\\\ +1 & -1 & +1 & -1 \\\\ -1 & +1 & -1 & +1 \\\\ \\end{vmatrix}\\)
对于列这样:
\\(\\begin{vmatrix} -1 & +1 & -1 & +1 \\\\ +1 & -1 & +1 & -1 \\\\ -1 & +1 & -1 & +1 \\\\ +1 & -1 & +1 & -1 \\\\ \\end{vmatrix}\\)
于是式子就分成了i+j为偶数和奇数两种情况。
最后连边跑一边差分约束即可。

AC代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int maxn=605;
const int maxx=1000000;
int n,m,T,p[maxn],dis[maxn],cnt,vis[maxn],times[maxn],a[305][305],b[305][305];
struct node{
	int v,next,w;
}e[305*305*2];
void insert(int u,int v,int w){
	cnt++;
	e[cnt].v=v;
	e[cnt].w=w;
	e[cnt].next=p[u];
	p[u]=cnt;
}
queue<int> q;
bool spfa(){
	while(!q.empty()) q.pop();
	memset(dis,0x3f,sizeof(dis));
	dis[0]=0;
	q.push(0);
	vis[0]=1;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		vis[u]=0;
		for(int i=p[u];i!=-1;i=e[i].next){
			int v=e[i].v;
			if(dis[v]>dis[u]+e[i].w){
				times[u]++;
				if(times[u]>n+m) return false;
				dis[v]=dis[u]+e[i].w;
				if(!vis[v]){
					vis[v]=1;
					q.push(v);
				}
			}
		}
	}
	return true;
}
int main(){
	scanf("%d",&T); 
	while(T--){
		cnt=0;
		memset(b,0,sizeof(b));
		memset(times,0,sizeof(times));
		memset(vis,0,sizeof(vis));
		memset(p,-1,sizeof(p));
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n+m;i++){
			insert(0,i,0);
		}
		for(int i=1;i<n;i++){
			for(int j=1;j<m;j++){
				scanf("%d",&a[i][j]);
			}
		}
		for(int i=n-1;i>=1;i--){
			for(int j=m-1;j>=1;j--){
				b[i][j]=a[i][j]-b[i+1][j]-b[i][j+1]-b[i+1][j+1];
			}
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if((i+j)%2==0){
					insert(i,j+n,b[i][j]);
					insert(j+n,i,maxx-b[i][j]);
				}else{
					insert(j+n,i,b[i][j]);
					insert(i,j+n,maxx-b[i][j]);
				}
			}
		}
		if(spfa()){
			printf("YES\\n");
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if((i+j)%2==0){
						printf("%d ",b[i][j]+dis[i]-dis[n+j]);
					}else{
						printf("%d ",b[i][j]-dis[i]+dis[n+j]);
					}
				}
				printf("\\n");
			}
		}else{
			printf("NO\\n");
		}
	}
	return 0;
}

以上是关于洛谷 P7515 [省选联考 2021 A 卷] 矩阵游戏(构造,差分约束)的主要内容,如果未能解决你的问题,请参考以下文章

luoguP6623 [省选联考 2020 A 卷] 树(trie树)

题解 省选联考2020 B卷 幸运数字

luoguP6620 [省选联考 2020 A 卷] 组合数问题(斯特林数)

[省选联考 2020 A 卷] 组合数问题 题解

P6625 [省选联考 2020 B 卷] 卡牌游戏

场外模拟 省选联考(A卷重考) 2020 游记