zoukankan      html  css  js  c++  java
  • hdu 2444 The Accomodation of Students

    http://acm.hdu.edu.cn/showproblem.php?pid=2444

      一道二分匹配的题,不过要在匹配前判断是否能形成二分图!这是我baidu二分匹配找到的题,我当时看到要判断是否为二分图就感到有点蒙了,因为看完数据结构太久了,忘记了二分图有什么特性了。当时我还打算按进去看代码,结果一按进去就发现bfs和dfs。刚切完一道hk算法的我头昏脑胀的,果断关了网页。

      在回宿舍的路上,我首先从bfs想到了可以判断是否有奇环。不过我想了好几个bfs的方法,都觉得复杂度挺大的,然后就直接抛弃了这个想法,另辟蹊径 !然后,我就发现,这些点和点间的关系有点像以前做过的一道并查集的题(poj 2492 A Bug's Life)。这样,好端端的朋友关系就因为要将人分成两堆而变成了敌对关系了!沿着这个思路,我打算先将人群分成好几组,然后在将他们根据敌对关系分成两份,最后再用匈牙利算法,因为规模才200,来解决余下的问题。

      回到宿舍了,我把我思路先写下来,然后就敲了一个并查集上去。不过在我想其他几个函数的结构的时候,突然来了这样的思路。既然两两相连的点之间是敌对关系,那么,确认了一个点的分组,与它相连的点的状态不就确定了吗!然后,这就是一个类似于bfs的方法,将一堆人分成了两份,但是我的方法缺了bfs常用的队列,从而节省了空间。

      分好组了,剩下的又是体力劳动了!不过比较囧的是,我的dfs里面居然因为打错了一个字母,搞到我debug了好几分钟....

      不过搞掂这个以后,提交的就是1y的代码了~~~Yeah!对二分匹配更熟悉了!对hk算法的熟悉程度还需加强,搞几题来练练手先~

    然后就是代码了:

    View Code
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <vector>
      5 
      6 using namespace std;
      7 
      8 const int maxn = 205;
      9 bool side[maxn], vis[maxn];
     10 int mt[maxn];
     11 vector<int> rel[maxn];
     12 
     13 int data(void){
     14     int n, m;
     15 
     16     if (scanf("%d%d", &n, &m) == -1) return -1;
     17     for (int i = 1; i <= n; i++){
     18         rel[i].clear();
     19     }
     20     for (int i = 0; i < m; i++){
     21         int a, b;
     22 
     23         scanf("%d%d", &a, &b);
     24         rel[a].push_back(b);
     25         rel[b].push_back(a);
     26     }
     27 
     28     return n;
     29 }
     30 
     31 bool attempt(int n){
     32     for (int i = 1; i <= n; i++){
     33         vis[i] = side[i] = false;
     34     }
     35     for (int i = 1; i <= n; i++){
     36         if (vis[i]){
     37             for (int j = 0; j < rel[i].size(); j++){
     38                 if (vis[rel[i][j]]){
     39                     if (side[rel[i][j]] == side[i]) return false;
     40                 }
     41                 else{
     42                     vis[rel[i][j]] = true;
     43                     side[rel[i][j]] = !side[i];
     44                 }
     45             }
     46         }
     47         else{
     48             vis[i] = side[i] = true;
     49             for (int j = 0; j < rel[i].size(); j++){
     50                 if (vis[rel[i][j]]){
     51                     if (side[rel[i][j]]) return false;
     52                 }
     53                 else{
     54                     vis[rel[i][j]] = true;
     55                     side[rel[i][j]] = false;
     56                 }
     57             }
     58         }
     59     }
     60 
     61     return true;
     62 }
     63 
     64 bool dfs(int v){
     65     for (int i = 0; i < rel[v].size(); i++){
     66         if (!vis[rel[v][i]]){
     67             vis[rel[v][i]] = true;
     68             if (mt[rel[v][i]] == -1 || dfs(mt[rel[v][i]])){
     69                 mt[rel[v][i]] = v;
     70 
     71                 return true;
     72             }
     73         }
     74     }
     75 
     76     return false;
     77 }
     78 
     79 int cal(int n){
     80     int cnt = 0;
     81 
     82 #ifndef ONLINE_JUDGE
     83     for (int i = 1; i <= n; i++){
     84         printf("side %d : %d     adj: ", i, side[i]);
     85         for (int j = 0; j < rel[i].size(); j++){
     86             printf("%d ", rel[i][j]);
     87         }
     88         puts("");
     89     }
     90 #endif
     91 
     92     for (int i = 1; i <= n; i++)
     93         mt[i] = -1;
     94     for (int i = 1; i <= n; i++){
     95         memset(vis, false, sizeof(vis));
     96         if (side[i] && dfs(i)){
     97             cnt++;
     98 #ifndef ONLINE_JUDGE
     99             printf("yes\n");
    100 #endif
    101 
    102         }
    103     }
    104 
    105     return cnt;
    106 }
    107 
    108 int main(){
    109     int n;
    110 
    111 #ifndef ONLINE_JUDGE
    112     freopen("in", "r", stdin);
    113 #endif
    114 
    115     while (~(n = data())){
    116         if (attempt(n)) printf("%d\n", cal(n));
    117         else printf("No\n");
    118     }
    119 
    120     return 0;
    121 }

    ——written by Lyon

  • 相关阅读:
    resin
    tomcat
    vba打开输入文件
    获取文件夹下所有文件2
    获取文件夹下所有文件
    修改Execl中sheet名的指定字符串为指定字符串
    SpringMVC入门到精通(一)
    Java JDBC
    Java反射
    Java日期格式化
  • 原文地址:https://www.cnblogs.com/LyonLys/p/hdu_2444_Lyon.html
Copyright © 2011-2022 走看看