## HDU 1068 Girls and Boys

HDU 1068 Girls and Boys

问题分析

给与 多组 可能存在关系 要求找出 最少没有配对的人

利用二分图法 匈牙利算法 编号指向另一个编号看做一条边

求出最大可以匹配 的 对数

详解看代码

AC代码如下

#include<iostream>
#include<cstring>
#include<cstdio>//scanf  printf 所在  必须加....深受其害
//或者直接万能头  #include<bits/stdc++.h> 
#include<algorithm>
using namespace std;
const int nn=1005;
int n,m;
int path[nn][nn];  //可能关系 标记数组 
bool  flag[nn];    // 访问  数组(具体看后面code) 
int match[nn];     //恋爱关系  指向数组 
int dfs(int i)  
{
    for(int j=0;j<n;j++)
    {
        if(!flag[j]&&path[i][j]){
		//这个男的没有被搜索过 并且 存在  可能的恋爱关系 
            flag[j]=1;//标记  
            if(match[j]==-1||dfs(match[j])){
			//  可能 会出现2种情况
			/*1.  这个男的在之前没有和任何女的建立关系
			  2.  已经 有关系了  但是  他通过  dfs能找到一个 没有和任何人
			  建立关系的女的   
			  3.  都没有 j++ 下一个男士..... 
			
			*/ 
                match[j]=i; 
                return 1;//建立了 关系  
            }
        }
    }
    return 0;
}
int main()
{
    while(~scanf("%d",&n)){
    	memset(path,0,sizeof(path));//每组重置 可能关系 
        memset(match,-1,sizeof(match));//重置 配对 
        for(int i=0;i<n;i++){
        	int x,y;
            scanf("%d: (%d)",&x,&m);
            while(m--){
                scanf("%d",&y);
                path[x][y]=1;  //建立男女关系 
            }
        }
        int sum=0;  //统计数组 
        for(int i=0;i<n;i++){
            memset(flag,0,sizeof(flag));
			//重置 男的 被选了  
			//为啥要重置?--> 因为 核心思想就是 替换  
			//如果不重置在  dfs时 第一道门槛给卡注了.. 
            if(dfs(i))
                sum++;
        cout<<n-sum/2<<endl;
        //  总数 减去最大匹配/2  即使 答案  
		//我们统计的  是 男女  和 女男 
		//因为 没有 明确的 界限 并且 在 dfs过程中 男女 都是交叉循环出现的(如果存在 dfs( match() )) 
        }
    }
    return 0;
}
posted @ 2019-11-04 20:04  MaxVen  阅读(111)  评论(0编辑  收藏  举报