ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P7515 [省选联考 2021 A 卷] 矩阵游戏

2022-02-10 21:03:43  阅读:147  来源: 互联网

标签:f1 le 省选 310 long times ch 联考 P7515


\(\texttt{Introduction}\)

差分约束好题,感觉是 \(\texttt{day1}\) 质量最高的一道题。

\(\texttt{Solution}\)

为了研究方便,现将矩形定为 \(4\times 4\) 的,然后再进行拓展。

首先这道题有一个非常重要的结论,就是我们只要知道第一行以及第一列,我们就可以推出整个矩形,那么我们只是可以列出这么一个表格:

A \(X_2\) \(X_3\) \(X_4\)
\(Y_2\) B(1,1)-X(2)-Y(2)-A B(1,2)-B(1,1)+Y(2)+A-X(3) B(1,3)-B(1,2)+B(1,1)-Y(2)-A-X(4)
\(Y_3\) B(2,1)-B(1,1)+X(2)+A-Y(3) B(2,2)-B(2,1)-A+Y(3)-B(1,2)+B(1,1)+X(3)
\(Y_4\)

那么做到这里我们考虑将与 \(B\) 有关的全部设成常数,记作 \(C(i,j)\) 。

那么现在就是对于每一对 \((i,j)\) 存在下列不等式:

\[C(i,j)+A\times (-1)^{i+j-1}+X_i\times (-1)^{j-1}+Y_j\times (-1)^{i-1}\ge 0 \]

\[C(i,j)+A\times (-1)^{i+j-1}+X_i\times (-1)^{j-1}+Y_j\times (-1)^{i-1}\le 10^6 \]

\[0\le A \le 10^6 \]

那么如果不考虑 \(A\) 的话这道题就是一道模板的差分约束,但是我们现在要知道这个 \(A\) 的值,那么是否可以通过微调实现?

我们根据 \(C(i,j)\) 再列一个表格。

A \(X_2\) \(X_3\) \(X_4\)
\(Y_2\) C(2,2)-X(2)-Y(2)-A C(2,3)+Y(2)+A-X(3) C(2,4)-Y(2)-A-X(4)
\(Y_3\) C(3,2)+X(2)+A-Y(3) C(3,3)-A+Y(3)+X(3) C(3,4)+A+X(4)-Y(3)
\(Y_4\) C(4,2)-X(2)-A-Y(4) C(4,3)-X(3)+A+Y(4) C(4,4)-X(4)-A-Y(4)

那么我们考虑假设:

\[E(i)=A+X(i),i为偶数;E(i)=A-X(i),i为奇数 \]

\[F(i)=-Y(i),i为偶数;F(i)=Y(i),i为奇数 \]

\[E(i)-10^6 \le A \le E(i),E(i) \le A \le E(i)+10^6 \]

#include <bits/stdc++.h>
using namespace std;
inline long long read() {
	long long x=0,f=1;
	char ch=getchar();
	while ((!isdigit(ch))&&(ch!='-')) ch=getchar();
	if (ch=='-') f=-1,ch=getchar();
	while (isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return x*f;
}
vector<pair<int,long long>> V[1010];
bool flag,vis[1010];
long long x,tag[1010],t,w,f1[10001010],Testing,n,m,i,j,cnt;
long long y,B[310][310],C[310][310],Answ[310][310],AA,dis[1010];
inline void add(int x,int y,int z) {
	V[x].push_back(make_pair(y,z));
}
int main() {
	//freopen("data.in","r",stdin);
	//freopen("TLE.out","w",stdout);
	Testing=read();
	for (; Testing; Testing--) {
		n=read();
		m=read();
		for (i=1; i<n; i++)for (j=1; j<m; j++) B[i][j]=read();
		for (i=2; i<=n; i++)
			for (j=2; j<=m; j++)
				C[i][j]=B[i-1][j-1]-C[i-1][j]-C[i][j-1]-C[i-1][j-1];
		
		//n+m-2个点
		for (i=2; i<=m; i++)
			for (j=2; j<=n; j++) {
				if (((i+j)&1)==0) {
					//0<=C(i,j)-E(i)+F(j)
					//E(i)-F(j)<=C(i,j)
					add(j+m,i,C[j][i]);
					//C(i,j)-E(i)+F(j)<=1000000
					//F(j)-E(i)<=1000000-C(i,j)
					add(i,j+m,1000000-C[j][i]);
				}
				if (((i+j)&1)==1) {
					//0<=C(i,j)+E(i)-F(j)<=1000000
					//F(j)-E(i)<=C(i,j)
					add(i,j+m,C[j][i]);
					add(j+m,i,1000000-C[j][i]);
				}
			}
		//E(i)>=0
		//E(0)-E(i)<=0
		//E(i)<=2000000
		//E(i)-E(0)<=2000000
		//E(i)+1000000>=0
		//E(i)>=-1000000
		//E(0)-E(i)<=1000000
		//E(i)<=1000000
		//E(i)-E(0)<=1000000
		//
		for (i=2; i<=m; i++)
			if (!(i&1)) {
				add(i,0,0);
				add(0,i,2000000);
			} else {
				add(i,0,1000000);
				add(0,i,1000000);
			}
		//E(0)-F(i)>=0
		//F(i)-E(0)<=0
		//F(i)-E(0)>=0
		//E(0)-F(i)<=0
		//-F(i)>=0
		//
		//-F(i)<=1000000
		//E(0)-F(i)<=1000000
		//F(i)<=1000000
		//F(i)-E(0)<=1000000
		//-F(i)>=0
		//F(i)-E(0)<=0
		for (i=2; i<=n; i++)
			if (!(i&1)) add(0,i+m,0),add(i+m,0,1000000);
			else add(i+m,0,0),add(0,i+m,1000000);
		for (i=2; i<=m; i++)
			for (j=i+1; j<=m; j++) {
				if ((!(i&1))&&(!(j&1))) {
					//E(i)-1000000<=E(j)
					//E(j)-1000000<=E(i)
					//E(i)-E(j)<=1000000,E(j)-E(i)<=1000000
					add(j,i,1000000);
					add(i,j,1000000);
				}
				if ((!(i&1))&&(j&1)) {
					//E(i)-1000000<=E(j)+1000000
					//E(i)-E(j)<=2000000
					//E(j)<=E(i)
					//E(j)-E(i)<=0
					add(j,i,2000000);
					add(i,j,0);
				}
				if ((i&1)&&(!(j&1))) {
					add(i,j,2000000);
					add(j,i,0);
				}
				if ((i&1)&&(j&1)) {
					//E(i)<=E(j)+1000000
					//E(j)<=E(i)+1000000
					//E
					add(j,i,1000000);
					add(i,j,1000000);

				}
			}
		for (i=0; i<=n+m+2; i++) dis[i]=1e18,tag[i]=0,vis[i]=false;
		t=1;
		w=1;
		dis[0]=0;
		f1[1]=0;
		flag=false;
		int sum = 0;
		while (t<=w) {
			if (flag) break;
			vis[f1[t]]=false;
			for (auto i:V[f1[t]])
			    {
				x=i.first;y=i.second;
				if (dis[x]>dis[f1[t]]+y) 
					{
						dis[x]=dis[f1[t]]+y;
						if ((tag[x]=tag[f1[t]]+1)>=n+m-1) {
							flag=true;
							break;
						}
						if (vis[x]==false) {
							w++;
							f1[w]=x;
							vis[x]=true;
						}
					}
				}
			t++;
		}
		for (i=0;i<=n+m+2;i++) V[i].clear();
		if (flag) puts("NO");
		else {
			puts("YES");
			AA=1e18;
			for (i=2; i<=m; i++)
				if (i % 2==0) AA=min(AA,dis[i]);
				else AA=min(AA,dis[i]+1000000);
		    AA=min(AA,(long long)1000000);
			Answ[1][1]=AA;
			for (i=2; i<=m; i++)
				if (i % 2==0)
					Answ[1][i]=dis[i]-AA;
				else Answ[1][i]=AA-dis[i];
			for (i=2; i<=n; i++)
				if (i % 2==1) Answ[i][1]=dis[i+m];
				else Answ[i][1]=-dis[i+m];
			for (i=2; i<=n; i++)
				for (j=2; j<=m; j++)
					Answ[i][j]=B[i-1][j-1]-Answ[i-1][j]-Answ[i-1][j-1]-Answ[i][j-1];
			for (i=1; i<=n; i++) {
				for (j=1; j<=m; j++)
				    {
					printf("%d ",Answ[i][j]);
				}
				puts("");
			}
		}
	}
	return 0;
}

被卡常了 /ll

woc,前向星竟然比不过邻接表。

标签:f1,le,省选,310,long,times,ch,联考,P7515
来源: https://www.cnblogs.com/oieralbedo/p/15880787.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有