zoukankan      html  css  js  c++  java
  • 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 }
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    【PAT甲级】1043 Is It a Binary Search Tree (25 分)(判断是否为BST的先序遍历并输出后序遍历)
    Educational Codeforces Round 73 (Rated for Div. 2)F(线段树,扫描线)
    【PAT甲级】1042 Shuffling Machine (20 分)
    【PAT甲级】1041 Be Unique (20 分)(多重集)
    【PAT甲级】1040 Longest Symmetric String (25 分)(cin.getline(s,1007))
    【PAT甲级】1039 Course List for Student (25 分)(vector嵌套于map,段错误原因未知)
    Codeforces Round #588 (Div. 2)E(DFS,思维,__gcd,树)
    2017-3-9 SQL server 数据库
    2017-3-8 学生信息展示习题
    2017-3-5 C#基础 函数--递归
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/7450598.html
Copyright © 2011-2022 走看看