poj1466 - Girls and Boys

133 篇文章 0 订阅

                                  想看更多的解题报告: http://blog.csdn.net/wangjian8006/article/details/7870410
                                  转载请注明出处:http://blog.csdn.net/wangjian8006

 

题目大意:有n个学生,每个学生都和一些人又关系,现在要你找出最大的人数,使得这些人之间没关系

解题思路:裸的最大独立集,最大独立集=点数-最大匹配数
这里注意因为是两两匹配,所以求出的匹配值要除上个2

优化了几下,时间不断减少

 

/*
Memory 1164K
Time   3844MS
*/
#include <iostream>
using namespace std;
#define MAXV 505

int map[MAXV][MAXV];
int n;
int link[MAXV],use[MAXV];

bool dfs(int x){
	int i,j;
	for(i=0;i<n;i++){
		if(!use[i] && map[x][i]){
			use[i]=1;
			if(link[i]==-1 || dfs(link[i])){
				link[i]=x;
				return true;
			}			
		}
	}
	return false;
}

int hungary(){
	int num=0,i;
	memset(link,-1,sizeof(link));
	for(i=0;i<n;i++){
		memset(use,0,sizeof(use));
		if(dfs(i)) num++;
	}
	return n-num/2;
}

int main(){
	int i,j,cnt;
	int a,b;
	while(~scanf("%d",&n)){
		memset(map,0,sizeof(map));
		for(i=0;i<n;i++){
			scanf("%d: (%d)",&a,&cnt);
			for(j=0;j<cnt;j++){
				scanf("%d",&b);
				map[a][b]=1;
			}
		}
		printf("%d\n",hungary());
	}
	return 0;
}

 

 

============================================================================================

 

 

/*
Memory  412K
Time  1391MS
*/
#include <iostream>
using namespace std;
#define MAXV 500

int vx[MAXV],vy[MAXV],n;
bool map[MAXV][MAXV];
bool use[MAXV];

bool dfs(int x){
	int i;
	for(i=0;i<n;i++){
		if(map[x][i] && !use[i]){
			use[i]=1;
			if(vy[i]==-1 || dfs(vy[i])){
				vy[i]=x;
				vx[x]=i;
				return true;
			}
		}
	}
	return false;
}

int hungary(){
	int i,num=0,j;
	memset(vx,-1,sizeof(vx));
	memset(vy,-1,sizeof(vy));
	for(i=0;i<n;i++){
		if(vx[i]==-1){
			for(j=0;j<n;j++) use[j]=0;
			if(dfs(i)) num++;
		}
	}
	return n-num/2;
}

int main(){
	int i,j,cnt;
	int a,b;
	while(~scanf("%d",&n)){
		memset(map,0,sizeof(map));
		for(i=0;i<n;i++){
			scanf("%d: (%d)",&a,&cnt);
			for(j=0;j<cnt;j++){
				scanf("%d",&b);
				map[a][b]=1;
			}
		}
		printf("%d\n",hungary());
	}
	return 0;
}



 

================================================================================================

 

 

/*
Memory 188K
Time  438MS
*/
#include <iostream>
using namespace std;
#define MAXV 500
#define MAXM 20000

typedef struct{
	int t,next;
}Edge;

Edge edge[MAXM];
int vx[MAXV],vy[MAXV],n,edge_sum;
int headlist[MAXV];
bool use[MAXV];

bool dfs(int x){
	int i,t;
	for(i=headlist[x];i!=-1;i=edge[i].next){
		t=edge[i].t;
		if(!use[t]){
			use[t]=1;
			if(vy[t]==-1 || dfs(vy[t])){
				vy[t]=x;
				vx[x]=t;
				return true;
			}
		}
	}
	return false;
}

int hungary(){
	int i,num=0,j;
	memset(vx,-1,sizeof(vx));
	memset(vy,-1,sizeof(vy));
	for(i=0;i<n;i++){
		if(vx[i]==-1){
			for(j=0;j<n;j++) use[j]=0;
			if(dfs(i)) num++;
		}
	}
	return n-num/2;
}

void add(int a,int b){
	edge[edge_sum].t=b;
	edge[edge_sum].next=headlist[a];
	headlist[a]=edge_sum++;
}

int main(){
	int i,j,cnt;
	int a,b;
	while(~scanf("%d",&n)){
		edge_sum=0;
		memset(headlist,-1,sizeof(headlist));
		for(i=0;i<n;i++){
			scanf("%d: (%d)",&a,&cnt);
			for(j=0;j<cnt;j++){
				scanf("%d",&b);
				add(a,b);
			}
		}
		printf("%d\n",hungary());
	}
	return 0;
}


 

 

=================================================================================================

 

 

/*
Memory 184K
Time  422MS
*/
#include <iostream>
using namespace std;
#define MAXV 500
#define MAXM 20000

typedef struct{
	int t,next;
}Edge;

Edge edge[MAXM];
int link[MAXV],n,edge_sum;
int headlist[MAXV];
bool use[MAXV];

bool dfs(int x){
	int i,t;
	for(i=headlist[x];i!=-1;i=edge[i].next){
		t=edge[i].t;
		if(!use[t]){
			use[t]=1;
			if(link[t]==-1 || dfs(link[t])){
				link[t]=x;
				return true;
			}			
		}
	}
	return false;
}

int hungary(){
	int num=0,i;
	memset(link,-1,sizeof(link));
	for(i=0;i<n;i++){
		memset(use,0,sizeof(use));
		if(dfs(i)) num++;
	}
	return n-num/2;
}

void add(int a,int b){
	edge[edge_sum].t=b;
	edge[edge_sum].next=headlist[a];
	headlist[a]=edge_sum++;
}

int main(){
	int i,j,cnt;
	int a,b;
	while(~scanf("%d",&n)){
		edge_sum=0;
		memset(headlist,-1,sizeof(headlist));
		for(i=0;i<n;i++){
			scanf("%d: (%d)",&a,&cnt);
			for(j=0;j<cnt;j++){
				scanf("%d",&b);
				add(a,b);
			}
		}
		printf("%d\n",hungary());
	}
	return 0;
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值