【匈牙利算法】BZOJ1059-[ZJOI2007]矩阵游戏

【题目大意】

给出一个局部染色的矩阵,问能否通过交换行或者列使得最后又一条对角线全部被染色过?

【思路】

无论如何交换,同一行的格子依然在同一行,同一列的格子依然在同一列。所以只需找出n个行号列号均不同的格子即可,裸的二分图匹配。

【错误点】

初始化出了问题。p忘记初始化+开始我将lk的初始值设为0,但是下标又是从0开始的,所以会出现lk[0]=0,其实它已经匹配过了,会出错所以将初始值改为了-1。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int MAXN=205;
 6 int p[MAXN][MAXN];
 7 int vis[MAXN],lk[MAXN];
 8 int n;
 9 
10 int find(int u)
11 {
12     for (int i=0;i<n;i++)
13         if (!vis[i] && p[u][i])
14         {
15             vis[i]=1;
16             if (lk[i]==-1 || find(lk[i]))
17             /*一开始我将lk的初始值设为0,但是下标又是从0开始的,所以会出现lk[0]=0,其实它已经匹配过了,会出错
18               所以将初始值改为了-1*/
19             {
20                 lk[i]=u;
21                 return 1;
22             }
23         }
24     return 0;
25 }
26 
27 void Hungary()
28 {
29     memset(lk,-1,sizeof(lk));
30     int ans=0;
31     for (int i=0;i<n;i++)
32     {
33         memset(vis,0,sizeof(vis));
34         if (find(i)) ans++;else break;
35     }
36     if (ans==n) cout<<"Yes"<<endl;else cout<<"No"<<endl;
37 }
38 
39 void init()
40 {
41     memset(p,0,sizeof(p));
42     /*这里忘记初始化了,多组数据的初始化要注意*/ 
43     scanf("%d",&n);
44     for (int i=0;i<n;i++)
45         for (int j=0;j<n;j++)
46         {
47             int x;
48             scanf("%d",&x);
49             if (x==1) 
50             {
51                 p[i][j]=1;
52             }
53         }
54 }
55 
56 int main()
57 {
58     int T;
59     scanf("%d",&T);
60     for (int kase=0;kase<T;kase++)
61     {
62         init();
63         Hungary();
64     }
65     return 0;
66 }

 

posted @ 2016-03-28 22:17  iiyiyi  阅读(158)  评论(0编辑  收藏  举报