Superdoku Kattis - superdoku (二分图匹配)

题目链接:

L - Superdoku

 Kattis - superdoku 

题目大意:给你一个n*n的矩阵,给你这个矩阵的前k行,问你是否能构成矩阵使得每一行每一列都是1~n的排列。

具体思路:首先我们记录每一行,每一列都有哪些数存在,然后从第k+1行开始,每一次就是1~n对(当前列中没有的数)的匹配,然后一共匹配1-n就可以了,逐行判断就可以了。

注意这里的net数组储存的是当前net[i],数字i指向的是哪一行,所以我们需要再开一个映射数组,当前行储存的是哪个数字。

AC代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 # define ll long long
  4 const int maxn = 2e5 + 100;
  5 const int N = 150;
  6 int a[N][N];
  7 int H[N][N],L[N][N];
  8 int net[N],vis[N];
  9 int ans[N];
 10 bool Find(int pos,int n)
 11 {
 12     for(int i=1; i<=n; i++)
 13     {
 14         if(L[pos][i]||vis[i])
 15             continue;
 16         vis[i]=1;
 17         if(net[i]==0||Find(net[i],n))
 18         {
 19             net[i]=pos;
 20             ans[pos]=i;
 21             return true;
 22         }
 23     }
 24     return false;
 25 }
 26 bool match(int pos,int n)
 27 {
 28     memset(net,0,sizeof(net));
 29     int num=0;
 30     for(int i=1; i<=n; i++)
 31     {
 32         memset(vis,0,sizeof(vis));
 33         if(Find(i,n))
 34             num++;
 35     }
 36    return num==n;
 37 }
 38 bool  solve(int n,int k)
 39 {
 40     int num=0;
 41     for(int i=k+1; i<=n; i++)
 42     {
 43         if(match(i,n))
 44             num++;
 45         for(int j=1; j<=n; j++)
 46         {
 47             a[i][j]=ans[j];
 48             H[i][ans[j]]=1;
 49             L[j][ans[j]]=1;
 50         }
 51     }
 52     return num==n-k;
 53 }
 54 int main()
 55 {
 56     int n,k;
 57     int flag=1;
 58     scanf("%d %d",&n,&k);
 59     for(int i=1; i<=k; i++)
 60     {
 61         for(int j=1; j<=n; j++)
 62         {
 63             scanf("%d",&a[i][j]);
 64             if(++H[i][a[i][j]]>2)
 65                 flag=0;
 66             if(++L[j][a[i][j]]>2)
 67                 flag=0;
 68         }
 69     }
 70     if(!flag)
 71         printf("no\n");
 72     else
 73     {
 74         if(k==0)
 75         {
 76             for(int i=1; i<=n; i++)
 77             {
 78                 a[1][i]=i;
 79                 H[1][i]=1;
 80                 L[i][i]=1;
 81             }
 82             k=1;
 83         }
 84         if(!solve(n,k))
 85         printf("no\n");
 86         else
 87         {
 88             printf("yes\n");
 89             for(int i=1; i<=n; i++)
 90             {
 91                 for(int j=1; j<=n; j++)
 92                 {
 93                     if(j==1)
 94                         printf("%d",a[i][j]);
 95                     else
 96                         printf(" %d",a[i][j]);
 97                 }
 98                 printf("\n");
 99             }
100         }
101     }
102     return 0;
103 }

 

posted @ 2019-05-05 11:04  Let_Life_Stop  阅读(512)  评论(0编辑  收藏  举报