HDU2819:Swap

来源:互联网 发布:大数据 个性化教育 编辑:程序博客网 时间:2024/05/23 19:50

点击打开题目链接

Swap

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1046    Accepted Submission(s): 348
Special Judge


Problem Description
Given an N*N matrix with each entry equal to 0 or 1. You can swap any two rows or any two columns. Can you find a way to make all the diagonal entries equal to 1?
 

Input
There are several test cases in the input. The first line of each test case is an integer N (1 <= N <= 100). Then N lines follow, each contains N numbers (0 or 1), separating by space, indicating the N*N matrix.
 

Output
For each test case, the first line contain the number of swaps M. Then M lines follow, whose format is “R a b” or “C a b”, indicating swapping the row a and row b, or swapping the column a and column b. (1 <= a, b <= N). Any correct answer will be accepted, but M should be more than 1000.

If it is impossible to make all the diagonal entries equal to 1, output only one one containing “-1”. 
 

Sample Input
20 11 021 01 0
 

Sample Output
1R 1 2-1
 

Source
2009 Multi-University Training Contest 1 - Host by TJU
 

Recommend
gaojie
 


=====================================题目大意=====================================


给出一个N阶的01方阵,求解通过交换行和交换列使得方阵的主对角线元素全部为1的任意一种方案。


=====================================算法分析=====================================


在给定的方阵中选取N个两两之间不同行不同列的1,然后便一定可以通过只交换行(或只交换列)移动这些1以得到所需的方阵。

显然二分图的最大匹配:将行和列作为两个点集,矩阵中的元素1作为连接其所在行和所在列的边,使用匈牙利算法求解即可。


=======================================代码=======================================




#include<stdio.h>#include<string.h>int N,Linker[105],RecordSwap[105][2];bool Edge[105][105],Vis[105];void Swap(int &A,int &B){int tmp=A;  A=B;  B=tmp;}bool DFS(int U){for(int v=1;v<=N;++v){if(Edge[U][v]&&!Vis[v])        {Vis[v]=true;if(Linker[v]==-1||DFS(Linker[v])){Linker[v]=U;return true;}         }     }     return false;}int Hungary(){    memset(Linker,-1,sizeof(Linker));int ans=0;    for(int u=1;u<=N;++u)    {        memset(Vis,0,sizeof(Vis));        if(DFS(u)) { ++ans; }    }     return ans;  }int main(){while(scanf("%d",&N)==1){for(int i=1;i<=N;++i){for(int j=1;j<=N;++j){scanf("%d",&Edge[i][j]);}}if(Hungary()<N){printf("-1\n");  continue;}int sum=0;for(int i=1;i<=N;++i) if(Linker[i]!=i){for(int j=i+1;j<=N;++j) if(Linker[j]==i){++sum;RecordSwap[sum][0]=i;RecordSwap[sum][1]=j;Swap(Linker[i],Linker[j]);}} printf("%d\n",sum);        for(int i=1;i<=sum;i++){            printf("C %d %d\n",RecordSwap[i][0],RecordSwap[i][1]);}    }return 0;}