zoukankan      html  css  js  c++  java
  • 【洛谷7515】[省选联考 2021 A 卷] 矩阵游戏(差分约束)

    点此看题面

    • 给出一个((n-1) imes(m-1))的矩阵(b)满足(b_{i,j}=a_{i,j}+a_{i,j+1}+a_{i+1,j}+a_{i+1,j+1}),要求构造一个(n imes m)的矩阵(a)满足所有数都在([0,10^6])范围内。
    • 数据组数(le10)(n,mle300)

    不论值域的随意构造

    先不管([0,10^6])这个值域限制,想要构造一组答案还是很简单的。

    我们不妨让最后一行和最后一列的数都为(0),然后从右下角开始枚举,则枚举到每个位置时它右方、下方、右下方的位置上的值都已经确定了,那么这个位置上的值也自然就确定了。

    差分约束

    考虑如果给某一行或某一列交错(pm1)是不会影响和的。

    我们给奇数行交错(mp1),给偶数行交错(pm1);给奇数列交错(pm1),给偶数列交错(mp1)

    发现就相当于要满足:

    [0le a_{i,j}+egin{cases}X_i-Y_j&i+j exttt{ is odd},\Y_j-X_i&i+j exttt{ is even}end{cases}le 10^6 ]

    相当于对于每个位置都可以列出两个差分约束的方程。

    经典差分约束建图之后,跑遍(SPFA)即可(如果存在负环说明无解)。

    代码:(O(Tnm(n+m)))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 300
    #define add(x,y,z) (G[x].push_back(make_pair(y,z))) 
    using namespace std;
    int n,m,a[N+5][N+5],b[N+5][N+5];vector<pair<int,int> > G[2*N+5];vector<pair<int,int> >::iterator it;
    int ct[2*N+5],IQ[2*N+5];long long dis[2*N+5];queue<int> q;I bool SPFA()//SPFA
    {
    	RI i,k,y;for(i=1;i<=n+m;++i) ct[i]=dis[i]=0,IQ[i]=1,q.push(i);W(!q.empty())
    	{
    		if(IQ[k=q.front()]=0,q.pop(),++ct[k]>n+m+1) {W(!q.empty()) q.pop();return 0;}//判负环
    		for(it=G[k].begin();it!=G[k].end();++it)
    			dis[k]+it->second<dis[y=it->first]&&(dis[y]=dis[k]+it->second,!IQ[y]&&(q.push(y),IQ[y]=1));
    	}return 1;
    }
    int main()
    {
    	RI Tt,i,j;scanf("%d",&Tt);W(Tt--)
    	{
    		for(scanf("%d%d",&n,&m),i=1;i<=n+m;++i) G[i].clear();//清空图
    		for(i=1;i^n;++i) for(j=1;j^m;++j) scanf("%d",&b[i][j]);
    		for(i=n;i;--i) for(j=m;j;--j) a[i][j]=i==n||j==m?0:b[i][j]-a[i+1][j]-a[i][j+1]-a[i+1][j+1],//随意构造
    			(i^j)&1?(add(i,n+j,a[i][j]),add(n+j,i,1e6-a[i][j])):(add(n+j,i,a[i][j]),add(i,n+j,1e6-a[i][j]));//列出两个差分方程建图
    		if(!SPFA()) {puts("NO");continue;}puts("YES");
    		for(i=1;i<=n;++i) for(j=1;j<=m;++j) printf("%d%c",a[i][j]+((i^j)&1?1:-1)*(dis[i]-dis[n+j])," 
    "[j==m]);//输出答案
    	}return 0;
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    截取url中最后斜杆的文件名
    html span从上往下,从左往右排序
    浪漫源码记录
    微信小程序TypeError: Cannot read property 'elem' of undefined
    tomcat8 性能优化
    Bandicam神奇使用法
    DataStage 七、在DS中使用配置文件分配资源
    DataStage 六、安装和部署集群环境
    DataStage 错误集(持续更新)
    DataStage 三、配置ODBC
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu7515.html
Copyright © 2011-2022 走看看