[关闭]
@xiaoziyao 2021-04-20T11:11:24.000000Z 字数 2768 阅读 1043

P7515 [省选联考 2021 A 卷] 矩阵游戏解题报告

解题报告


P7515 [省选联考 2021 A 卷] 矩阵游戏解题报告:

更好的阅读体验

题意

给定大小为的矩阵,求生成任意一个满足条件的满足:

保证

分析

可能是暗中送我退役的一道题,我要是把这个思路想下去做掉这道题,那我剩下的题用头打都能进队啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!

技不如人,肝败吓疯。

首先不考虑,并钦定,不难发现可以生成一组解

我们考虑通过调整某些位置的权值使得最后的解权值满足限制。

发现对某一行交替后的解仍然满足矩阵的限制;同理,对某一列交替后的解也仍然满足矩阵的限制。

不难发现任意一组解都可以被这样表示出来:

再考虑这一限制,不难发现把序列与序列看做未知量之后可以对其进行差分约束。

但是对于同号的不等式是很难进行差分约束的,考虑定义,

然后再次带入上面的解可以得到一个很优美的形式:

这样就可以进行差分约束了,复杂度:

代码

Bellman Ford被卡常了(需要特判才能过),迫不得已用了spfa/kk

  1. #include<stdio.h>
  2. #include<queue>
  3. #include<vector>
  4. #define inf 10000000000000000
  5. using namespace std;
  6. const int maxn=305,maxm=maxn*maxn*2;
  7. int T,n,m,e;
  8. int a[maxn][maxn],b[maxn][maxn],vis[maxn<<1],tot[maxn<<1];
  9. vector<int>v[maxn<<1],w[maxn<<1];
  10. long long dis[maxn<<1];
  11. queue<int>q;
  12. inline void add(int x,int y,int z){
  13. v[x].push_back(y),w[x].push_back(z);
  14. }
  15. inline void limit(int x,int y,int v){
  16. add(x,y,v);//v+x-y>=0
  17. add(y,x,1000000-v);//v+x-y<=1000000
  18. }
  19. int spfa(){
  20. while(!q.empty())
  21. q.pop();
  22. for(int i=1;i<=n+m;i++)
  23. dis[i]=inf,tot[i]=0,vis[i]=0;
  24. dis[1]=0,vis[1]=1,q.push(1);
  25. while(!q.empty()){
  26. int x=q.front();
  27. tot[x]++;
  28. if(tot[x]>n+m)
  29. return 1;
  30. q.pop();
  31. for(int i=0;i<v[x].size();i++){
  32. int y=v[x][i],z=w[x][i];
  33. if(dis[y]>dis[x]+z){
  34. dis[y]=dis[x]+z;
  35. if(vis[y]==0)
  36. vis[y]=1,q.push(y);
  37. }
  38. }
  39. vis[x]=0;
  40. }
  41. return 0;
  42. }
  43. inline int calc(int x,int y){
  44. return a[x][y]+(int)(((x+y)&1)? (dis[n+y]-dis[x]):(dis[x]-dis[n+y]));
  45. }
  46. int main(){
  47. scanf("%d",&T);
  48. while(T--){
  49. e=0;
  50. scanf("%d%d",&n,&m);
  51. for(int i=1;i<n;i++)
  52. for(int j=1;j<m;j++)
  53. scanf("%d",&b[i][j]);
  54. for(int i=2;i<=n;i++)
  55. for(int j=2;j<=m;j++)
  56. a[i][j]=b[i-1][j-1]-a[i-1][j-1]-a[i-1][j]-a[i][j-1];
  57. for(int i=1;i<=n;i++)
  58. for(int j=1;j<=m;j++){
  59. if((i+j)&1)
  60. limit(n+j,i,a[i][j]);
  61. else limit(i,n+j,a[i][j]);
  62. }
  63. if(spfa()){
  64. puts("NO");
  65. for(int i=1;i<=n+m;i++)
  66. v[i].clear(),w[i].clear();
  67. continue;
  68. }
  69. puts("YES");
  70. for(int i=1;i<=n;i++)
  71. for(int j=1;j<=m;j++)
  72. printf("%d%c",calc(i,j),j==m? '\n':' '),a[i][j]=0;
  73. for(int i=1;i<=n+m;i++)
  74. v[i].clear(),w[i].clear();
  75. }
  76. return 0;
  77. }

省选联考A卷全部题解可见:2021省选联考A卷解题报告

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注