Swap HDU

来源:互联网 发布:幂学集训营怎么样 知乎 编辑:程序博客网 时间:2024/05/22 09:43

Swap

HDU - 2819

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

详细解释

我在代码中又具体解释了下路径输出的过程、

code:

#include <iostream>#include <cstring>#include <cstdio>using namespace std;#define INF 0x3f3f3f3f#define MAXN 105bool G[MAXN][MAXN],vis[MAXN];int match[MAXN],N,M,T,a[MAXN],b[MAXN];bool dfs(int u){int i;for(i = 0; i <= N; i++){if(G[u][i] && !vis[i]){vis[i] = true;if(!match[i] || dfs(match[i])){match[i] = u;return true;}}}return false;}int main(){while(~scanf("%d",&N)){memset(G,0,sizeof(G));memset(match,0,sizeof(match));int x,ans = 0;int i,j;for(i = 1; i <= N; i++){for(j = 1; j <= N; j++){scanf("%d",&x);if(x)  G[i][j] = true;}}for(i = 1; i <= N; i++){memset(vis,0,sizeof(vis));if(dfs(i))  ans++;}//上面代码就是简单的求最大二分匹配的模板 if(ans < N){//如果最大二分匹配小于N,则说明矩阵的秩不是N,一定无法达到要求 printf("-1\n");continue;}//以下是路径还原 int tot = 0;//就目前来说,我们通过二分图最大匹配得到的match匹配数组只是证明这个矩阵的秩是n,可以通过//交换得到,对角线都是1,并且已经记录下了匹配(即谁和谁进行交换),但是还没有进行交换//实际上下面的任务只是根据match数组给我们指令,进行模拟交换一下就可以了,顺便记录下每次是//谁和谁交换的即可 for(i = 1; i <= N; i++){//每个点都当做一个起点 (行号i) for(j = 1; j <= N && match[j] != i; j++);//找到与之匹配的那个点(列号j)match[j]=i就是将j列的1移动到i列得到G[i][i]=1,完成一次交换 if(i != j){//只有当ij不相等才需要交换,如果相等说明原来这个点就在对角线上不用交换了 a[tot] = i;b[tot] = j;//记录下交换的路径 tot++;//交换完了,那就要真的交换过来,只需要交换match数组即可,就实现的j列和i列的交换,即j列现在对应了原来i列所对应的行号i',反之亦然 int t = match[i];match[i] = match[j];match[j] = t;}}printf("%d\n",tot);for(i = 0; i < tot; i++)   printf("C %d %d\n",a[i],b[i]);//cout << "----------------------------------------------" << endl;}return 0;}


原创粉丝点击