poj2594 机器人寻找宝藏(最小路径覆盖)

题目来源:http://poj.org/problem?id=2594

参考博客:http://www.cnblogs.com/ka200812/archive/2011/07/31/2122641.html

题解:

最小路径覆盖=|P|-最大匹配数

 单向图且没有循环,不可能存在a到b,b又到a,并且可以经过已经经过的点,所以对整个图进行处理,间接连接的点可以看作是直接连接

将整个图分成两边,点与点二分匹配,与平时的两种不同物体匹配不同

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=500+5;
int ma[maxn][maxn],match[maxn];
bool used[maxn];
int n;
void floyed(){
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(ma[i][k]+ma[k][j]==2)ma[i][j]=1;
}
bool dfs(int x){
	for(int i=1;i<=n;i++){
		if(ma[x][i]&&used[i]==0){
			used[i]=1;
			if(match[i]==0||dfs(match[i])){
				match[i]=x;
				return 1;
			}

		}
	}
	return 0;
}
int solve(){
	memset(match,0,sizeof(match));
	int ans=0;
	for(int i=1;i<=n;i++){
		memset(used,0,sizeof(used));
		if(dfs(i))ans++;
	}
	return n-ans;
}
int main()
{
	int m;
	while(scanf("%d %d",&n,&m)==2){
		if(n==0&&m==0)break;
		memset(ma,0,sizeof(ma));
		for(int i=1;i<=m;i++){
			int a,b;
			scanf("%d %d",&a,&b);
			ma[a][b]=1;
		}
		floyed();
		cout<<solve()<<endl;
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/carcar/p/9143382.html