二分匹配 -- Swap HDU - 2819

Swap HDU - 2819

思路:

在这里插入图片描述

#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
const int maxn = 1e2 + 5;
bool vis[maxn];
int mp[maxn][maxn], match[maxn];
int n;
pair<int, int> pai[maxn * 2];
bool dfs(int u){
	for(int i = 1; i <= n; i++){
		int v = i;
		if(!mp[u][v] || vis[v]) continue;
		vis[v] = true;
		if(!match[v] || dfs(match[v])){
			match[v] = u;
			return true;
		}
	}
	return false;
}

int main(){
	while(~scanf("%d", &n)){
	    for(int i = 1; i <= n; i++) match[i] = 0;
		
		for(int i = 1; i <= n; i++)
		   for(int j = 1; j <= n; j++)
			  scanf("%d", &mp[i][j]); 
			  
		int cot = 0;
		for(int i = 1; i <= n; i++){
			for(int j = 1; j <= n; j++) vis[j] = false;
			if(dfs(i)) cot++;
		}
		
		if(cot < n) printf("-1\n");
		else {
		
//          int opt = 0;
//			for(int i = 1; i <= n; i++) if(match[i] != i) opt++;
//			printf("%d\n", --opt); 
//			for(int i = 1; i < n; i++){
//				for(int j = i + 1; j <= n; j++)
//				   if(i == match[j]) {
//					  swap(match[i], match[j]);
//					  printf("C %d %d\n", i, j);
//				   }
//			}
			int opt = 0;   //注意:opt这里是个坑点,不能像上面那么计算,
			for(int i = 1; i <= n; i++){  //因为当有多个match[i]和matcch[j]
			                              //恰好互补时,上面的计算就是错的
				while(match[i] != i){
					pai[++opt].first = i;
					pai[opt].second = match[i];
					swap(match[i], match[match[i]]);
				}
				
			}
			
			printf("%d\n", opt);
			for(int i = 1; i <= opt; i++) printf("C %d %d\n", pai[i].first, pai[i].second);
		
		}	  
	 
		
	}
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值