HDU 2819 矩阵 最大二分匹配

Swap

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2223    Accepted Submission(s): 797
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
  
  
2 0 1 1 0 2 1 0 1 0
 

Sample Output
  
  
1 R 1 2 -1
 

Source
 




题目要求对角线上为1  也就是矩阵的秩为n  如果秩不为n  那么不管交换行还是交换列都是无解的 

于是我只交换列  用最大二分匹配匹配秩是否为n 也就是做出一个

1 0 0

0 1 0

0 0 1 

的图



于是代码就出炉了


#include<stdio.h>
#include<string.h>

bool imap[111][111],b[111];
int p[111],n;

bool findorz(int x){
	int y;
	for(y=1;y<=n;y++){
		if(imap[x][y]&&!b[y]){
			b[y]=1;
			if(!p[y]||findorz(p[y])){
				p[y]=x;
				return true;
			}
			
		}
	}
	return false;
}



int main(){
	int i,j,k,l,m,orz,op1[111],op2[111];
	while(~scanf("%d",&n)){
		orz=0; 
		memset(p,0,sizeof(p));
		memset(imap,0,sizeof(imap));
		for(i=1;i<=n;i++){
			for(j=1;j<=n;j++){
				scanf("%d",&orz);
				if(orz)	imap[i][j]=true;
			}
		}
		orz=0;
		for(i=1;i<=n;i++){
			memset(b,0,sizeof(b));
			if(findorz(i)){
				orz++;
			}
		}
		if(orz<n){
			printf("-1\n");
			continue;
		}
		orz=0;
		for(i=1;i<=n;i++){
			/*
			for(j=1;j<=n;j++){
				if(p[j]==i) break;
			}*/
			for(j=1;j<=n && p[j]!=i ;j++);
			if(i!=j){
				op1[orz]=i;  op2[orz]=j; orz++;
				int t=p[j];
				p[j]=p[i];
				p[i]=t;
			}
			
		}
		printf("%d\n",orz);
		for(i=0;i<orz;i++){
			printf("C %d %d\n",op1[i],op2[i]);
		}
	}
}

快速的打好了代码。。然后怎么交都错。。发现匈牙利算法中搜索的东西少打了。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值