• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
LyonLys
愿意在角落唱沙哑的歌 再大声也都是给你 请用心听 不要说话 Contact me via E-mail: lyon.lys@gmail.com
博客园    首页    新随笔    联系   管理    订阅  订阅

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

posted @ 2012-08-13 20:49  LyonLys  阅读(188)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3