luogu P1129 [ZJOI2007]矩阵游戏

传送门

要使得经过一系列移动后对角线上全是黑的,也就是要存在\(n\)个点,满足每行都只有一个,以及每列都只有一个,这\(n\)个棋子也就是所在行和所在列一一匹配

于是把题目给的矩阵当成二分图邻接矩阵,然后最大匹配救星了

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))

using namespace std;
const int N=200+10;
il LL rd()
{
    re LL x=0,w=1;re char ch=0;
    while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
}
int n;
int vis[N],ti,mp[N][N],mat[N];
bool xyl(int x)
{
  for(int y=1;y<=n;y++)
    if(mp[x][y]&&vis[y]<ti)
      {
        vis[y]=ti;
        if(!mat[y]||xyl(mat[y])) {mat[y]=x;return true;}
      }
  return false;
}

int main()
{
  int T=rd();
  while(T--)
    {
      memset(vis,0,sizeof(vis));
      memset(mat,0,sizeof(mat));
      n=rd();
      for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
          mp[i][j]=rd();
      bool ok=true;
      for(int i=1;i<=n&&ok;i++)
        ++ti,ok&=xyl(i);
      printf("%s\n",ok?"Yes":"No");
    }
  return 0;
}

posted @ 2018-09-25 22:16  ✡smy✡  阅读(77)  评论(0编辑  收藏  举报