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;
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容