传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2819
解题思路:
这道题是要把n×n的矩阵的对角线全部变为一。
然后我们把纵坐标,横坐标分别为二分图的左右两个集合,如果要对角线全部为1。
首先要满足的条件是:
这个二分图的最大匹配数,必须为N,如果小于肯定不能满足题意。换句话说每一个列都必须和一个行有匹配。
然后进行交换就行了。
实现代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int MAXN=105; 8 int g[MAXN][MAXN],used[MAXN]; 9 int linker[MAXN]; 10 int N; 11 int a[MAXN*10],b[MAXN*10]; 12 13 bool dfs(int u){ 14 for(int i=1;i<=N;i++){ 15 if(!used[i]&&g[u][i]){ 16 used[i]=1; 17 if(linker[i]==-1||dfs(linker[i])){ 18 linker[i]=u; 19 return true; 20 } 21 } 22 } 23 return false; 24 } 25 26 int hungry(){ 27 memset(linker,-1,sizeof(linker)); 28 int res=0; 29 30 for(int i=1;i<=N;i++){ 31 memset(used,0,sizeof(used)); 32 if(dfs(i)) 33 res++; 34 } 35 return res; 36 } 37 38 int main(){ 39 while(scanf("%d",&N)!=EOF){ 40 for(int i=1;i<=N;i++) 41 for(int j=1;j<=N;j++) 42 scanf("%d",&g[i][j]); 43 44 int ans=hungry(); 45 if(ans<N){ 46 printf("-1 "); 47 continue; 48 } 49 50 int res=0; 51 int i,j; 52 for(i=1;i<=N;i++){ 53 54 //第i列要和和与第i行匹配的列相交换。 55 for(j=i;j<=N;j++) 56 if(linker[j]==i) 57 break; 58 if(i!=j){ 59 a[res]=i;b[res++]=j; 60 swap(linker[i],linker[j]); 61 } 62 } 63 64 printf("%d ",res); 65 for(i=0;i<res;i++) 66 printf("C %d %d ",a[i],b[i]); 67 } 68 69 }