(step6.3.5)hdu 1281(棋盘游戏——二分图的完美匹配)

题目大意:本体是中文题。读者可以直接在OJ上看


解题思路:


1)完美匹配:所有的端点都是匹配点

2)对于二分图的完美匹配,我们需要用一个数组来存储匹配点。(而二分图的其他问题(我们则可以直接使用变量来存储即可)

for(i = 1 ; i <= k ; ++i){
//			int a,b对于完美匹配的题,需要用数组记录下匹配点。假如不是完美匹配的二分图的题。直接用a,b即可
			scanf("%d%d",&a[i],&b[i]);
			map[a[i]][b[i]] = 1;
		}


3)解决完美匹配问题的核心代码:


代码如下:

int count = 0;
		for(i = 1 ; i <= k ; ++i){
			map[a[i]][b[i]] = 0;
			int d = max_match();
			map[a[i]][b[i]] = 1;
			if(d != num){//如果d!=num,则说明该点是匹配点.
				count++;
			}
		}



代码如下:

/*
 * 1281_1.cpp
 *
 *  Created on: 2013年8月31日
 *      Author: Administrator
 */


#include <iostream>

using namespace std;

const int maxn = 101;
int map[maxn][maxn];
int link[maxn];
bool useif[maxn];
int n,m;

int can(int t){
	int i;
	for(i = 1 ; i <= m ; ++i){
		if(useif[i] == 0 && map[t][i]){
			useif[i] = 1;
			if(link[i] == -1 || can(link[i]) ){
				link[i] = t;
				return 1;
			}
		}
	}
	return 0;
}


int max_match(){
	int i;
	int num = 0;
	memset(link,-1,sizeof(link));
	for(i = 1 ; i <= n ; ++i){
		memset(useif,0,sizeof(useif));
		if(can(i)){
			num++;
		}
	}
	return num;
}

int main(){
	int k;
	int counter = 1;
	while(scanf("%d%d%d",&n,&m,&k)!=EOF){
		int i;
		int a[k+1],b[k+1];
		memset(map,0,sizeof(map));
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		for(i = 1 ; i <= k ; ++i){
//			int a,b对于完美匹配的题,需要用数组记录下匹配点。假如不是完美匹配的二分图的题。直接用a,b即可
			scanf("%d%d",&a[i],&b[i]);
			map[a[i]][b[i]] = 1;
		}

		int num = max_match();

		int count = 0;
		for(i = 1 ; i <= k ; ++i){
			map[a[i]][b[i]] = 0;
			int d = max_match();
			map[a[i]][b[i]] = 1;
			if(d != num){//如果d!=num,则说明该点是匹配点.
				count++;
			}
		}

		printf("Board %d have %d important blanks for %d chessmen.
",counter++,count,num);
	}
}


原文地址:https://www.cnblogs.com/keanuyaoo/p/3294098.html