POJ 3020 Antenna Placement(最短路径覆盖)

版权声明:听说这里让写版权声明~~~ https://blog.csdn.net/m0_37691414/article/details/82114560

解析:最小路径数=结尾结点数 = n- 非结尾结点数 = n - 最大匹配数。 所以,
最小路径覆盖数 = 结点数 - 最大匹配数。此为有向图。
无向二分图的最小路径覆盖 = 顶点数 – 最大二分匹配数/2

科普一下二分图的知识点

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N = 600;
int map[N][N];
int e[N][N], line[N];
bool visit[N];
int dir[4][2] = {1, 0, 0, 1, 0, -1, -1, 0};
int n, m;
int find(int x){
	for(int i = 1; i <= m; ++i){
		if(visit[i] == false && e[x][i]){
			visit[i] = true;
			if(line[i] == -1 || find(line[i])){
				line[i] = x;
				return 1;
			}
		}
	}
	return 0;
}
int main(){
	int t;
	scanf("%d", &t);
	while(t--){
		memset(e, 0, sizeof(e));
		memset(map, 0, sizeof(map));
		cin >> m >> n;
		int cnt = 0;
		char c;
		for(int i = 1; i <= m; ++i)
			for(int j = 1; j <= n; ++j){
				cin >> c;
				if(c == '*')	map[i][j] = ++cnt;
			}
		for(int i = 1; i <= m; ++i)
			for(int j = 1; j <= n; ++j){
				if(map[i][j]){
					for(int k = 0; k < 4; ++k){
						int x = i + dir[k][0];
						int y = j + dir[k][1];
						if(x > 0 && x <= m && y >0 && y <= n && map[x][y])	e[map[i][j]][map[x][y]] = 1;
					}
				}
			}
		m = n = cnt;
		int num = 0;
		memset(line, -1, sizeof(line));
		for(int i = 1; i <= n; ++i){
			memset(visit, false, sizeof(visit));
			if(find(i))	num++;
		}
		printf("%d\n", n - num / 2);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37691414/article/details/82114560
今日推荐