Hdu 1068(匈牙利算法+最大独立集)

Hdu 1068

(1)思路:

用匈牙利算法求出最大匹配,然后求出最大独立集 = n - 最大匹配 = n - (最大匹配的点数)/2.

(2)匈牙利算法:

匈牙利算法是用来求解最大匹配算法;

算法的基本思想是寻找图中的增广路径,从一个点开始下一个未匹配点,如果找到下一个未匹配点,

就说明找到了一条新的增广路径,将新的匹配边加入增广路径,然后将之前的匹配边与非匹配边取反,

得到新的增广路径。

如果每次寻找的这个点能够找到新的增广路径,最大匹配的点的数量+1.

(3)代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e5+10;
int head[maxn],vis[maxn],pre[maxn],m,n,tot;
struct Node{
	int v,nxt;
}cur[maxn<<2];
void Init(){
	memset(head,-1,sizeof(head));
	tot = 0;
}
void Add(int x,int y){
	cur[tot].nxt = head[x];
	cur[tot].v = y;
	head[x] = tot++;
}
bool dfs(int x){
	for(int i=head[x];i!=-1;i=cur[i].nxt){
		int y = cur[i].v;
		if(vis[y]==0){
			vis[y] = 1;
			if(pre[y]==-1||dfs(pre[y])){
				pre[y] = x;
				return true;
			}
		}
	}
	return false;
}
int fun(){
	memset(pre,-1,sizeof(pre));
	int ans = 0;
	for(int i=0;i<n;i++){
		memset(vis,0,sizeof(vis));
		if(dfs(i)) ans++;
	}
	return ans;
}
int main(void){
	while(~scanf("%d",&n)){
		Init();
		for(int i=0;i<n;i++){
			int x,y;
			scanf("%d: (%d) ",&x,&y);
			for(int j=0;j<y;j++){
				int z;scanf("%d",&z);
				Add(x,z);
			}
		}
		
		int ans = n-fun()/2;
		printf("%d\n",ans); 
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41829060/article/details/92087259
今日推荐