【匈牙利算法】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 }