hdu 3829 Cat VS Dog

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

  这道题是一道二分匹配。这题虽然猫和狗是对立的,不过却要用小朋友的关系来构图。让我详细的说还真的挺难说的懂,反正就是如果两个小朋友间讨厌的动物是另一个的喜欢的动物,那么这两个小朋友之间就得连上一条边。这里可以理解为两个小朋友间产生了敌对的关系了。为了大家和睦相处,只好消灭足够多的敌对关系了,于是最大匹配的算法就出现了!

  虽然这次数据规模不大,不过我还是用了hk算法,拿来练习!这次刚打出来的代码反映出我过往打hk算法的一个问题,在dfs前忘记判断这个x点是否已经匹配了!可笑的是,我以前的代码都过了,这次就因为这个问题TLE,应该是进入死循环了,所以我之前的几篇hk算法的代码都修正了这个问题!

然后就是我的代码:(31ms with g++通过)

View Code
  1 #include <cstdlib>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <vector>
  6 
  7 using namespace std;
  8 
  9 const int maxn = 505;
 10 struct person{
 11     char l[10]; // record like animal
 12     char h[10]; // record hate animal
 13 }p[maxn];
 14 vector<int> rel[maxn];
 15 
 16 int mx[maxn], my[maxn];
 17 int rx[maxn], ry[maxn];
 18 int q[maxn << 1], qf, qb;
 19 
 20 bool bfs(int n){
 21     bool ret = false;
 22 
 23     qf = qb = 0;
 24     for (int i = 0; i < n; i++){
 25         rx[i] = ry[i] = 0;
 26         if (mx[i] == -1) q[qb++] = i;
 27     }
 28 
 29     while (qf < qb){
 30         int cur = q[qf++];
 31 #ifndef ONLINE_JUDGE
 32         printf("cur %d\n", cur);
 33 #endif
 34 
 35         for (int i = 0; i < rel[cur].size(); i++){
 36             int t = rel[cur][i];
 37 
 38             if (!ry[t]){
 39                 ry[t] = rx[cur] + 1;
 40                 if (my[t] == -1){
 41                     ret = true;
 42                 }
 43                 else{
 44                     rx[my[t]] = ry[t] + 1;
 45                     q[qb++] = my[t];
 46                 }
 47             }
 48         }
 49     }
 50 
 51     return ret;
 52 }
 53 
 54 bool dfs(int cur){
 55     for (int i = 0; i < rel[cur].size(); i++){
 56         int t = rel[cur][i];
 57 
 58         if (ry[t] == rx[cur] + 1){
 59             ry[t] = 0;
 60             if (my[t] == -1 || dfs(my[t])){
 61                 my[t] = cur;
 62                 mx[cur] = t;
 63 
 64                 return true;
 65             }
 66         }
 67     }
 68     return false;
 69 }
 70 
 71 int hk(int n){
 72     int cnt = 0;
 73 
 74     for (int i = 0; i < n; i++){
 75         mx[i] = my[i] = -1;
 76     }
 77     while (bfs(n)){
 78         for (int i = 0; i < n; i++){
 79             if (mx[i] == -1 && dfs(i)) cnt++;
 80         }
 81     }
 82 
 83     return cnt;
 84 }
 85 
 86 bool deal(){
 87     int n, m, P;
 88 
 89     if (scanf("%d%d%d", &n, &m, &P) == EOF) return false;
 90     for (int i = 0; i < P; i++){
 91         scanf("%s%s", p[i].l,  p[i].h);
 92         rel[i].clear();
 93         for (int j = 0; j < i; j++){
 94             if (!strcmp(p[i].l, p[j].h) || !strcmp(p[i].h, p[j].l)){
 95                 rel[i].push_back(j);
 96                 rel[j].push_back(i);
 97             }
 98         }
 99     }
100     printf("%d\n", P - hk(P) / 2);
101 
102     return true;
103 }
104 
105 int main(){
106 #ifndef ONLINE_JUDGE
107     freopen("in", "r", stdin);
108 #endif
109     while (deal());
110 
111     return 0;
112 }

——written by Lyon

原文地址:https://www.cnblogs.com/LyonLys/p/hdu_3829_Lyon.html