• HDU2444


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2444

    题目大意:

      n个学生,他们中间有m对互相认识。有两个操作:

      1、把所有人分成两组,每组中的人都互不认识。若该操作能完成,那么请考虑操作2,否则输出“No”;

      2、将互相认识的两个人分配到一间双人房,问最多能分出多少间房。

      其实操作1就是要我们做一个二分图判定,我们用一个DFS就能完成,详见《挑战程序设计竞赛》P97。在确定这是一个二分图的前提下,我们就能根据学生之间的关系写一个匈牙利算法来求最大匹配数,最大匹配数其实就是最多的房间数。由于在程序中,我把每个房间当成了两个来进行匹配,所以最后的最大匹配数要除以2。

    AC代码:

     1 #include <cstring>
     2 #include <vector>
     3 #include <cstdio>
     4 using namespace std;
     5 const int maxn=204;
     6 bool link[maxn][maxn], vis[maxn];
     7 int r[maxn],n,color[maxn];
     8 vector<int> G[maxn];
     9 bool finds(int x){
    10     for(int i=1;i<=n;i++){
    11         if(!vis[i]&&link[x][i]){
    12             vis[i]=true;
    13             if(r[i]==0||finds(r[i])){
    14                 r[i]=x;
    15                 return true;
    16             }
    17         }
    18     }
    19     return false;
    20 }
    21 bool dfs(int v,int c){
    22     color[v]=c;
    23     for(int i=0;i<G[v].size();i++){
    24         if(color[G[v][i]]==c)   return false;
    25         if(color[G[v][i]]==0&&!dfs(G[v][i],-c)) return false;
    26     }
    27     return true;
    28 }
    29 bool yes_no(){
    30     for(int i=1;i<=n;i++){
    31         if(color[i]==0){
    32             if(!dfs(i,1))  return false;
    33         }
    34     }
    35     return true;
    36 }
    37 int main(){
    38     int m,a,b;
    39     while(scanf("%d%d",&n,&m)==2){
    40         memset(color,0,sizeof(color));
    41         memset(link,false,sizeof(link));
    42         memset(r,0,sizeof(r));
    43         for(int i=1;i<=n;i++)   G[i].clear();
    44         while(m--){
    45             scanf("%d%d",&a,&b);
    46             G[a].push_back(b),G[b].push_back(a);
    47             link[a][b]=link[b][a]=true;
    48         }
    49         if(!yes_no()){
    50             printf("No
    ");
    51             continue;
    52         }
    53         int ans=0;
    54         for(int i=1;i<=n;i++){
    55             memset(vis,false,sizeof(vis));
    56             if(finds(i))    ans++;
    57         }
    58         printf("%d
    ",ans/2);
    59     }
    60     return 0;
    61 }
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    第七周——Linux内核如何装载和启动一个可执行程序
    第十八章读书笔记
    第三章读书笔记
    第六周——分析Linux内核创建一个新进程的过程
    第五章读书笔记
    Linux内核分析——分析system_call中断处理过程
    第一二章读书笔记
    20145217《网络对抗》 Web安全基础实践
    20145217《网络对抗》web基础
    20145217《网络对抗》 MSF基础应用
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/7450598.html
Copyright © 2020-2023  润新知