zoukankan      html  css  js  c++  java
  • 二分图匹配-HK算法

    先把代码贴上,其他南京回来再补了。。

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <iostream>
      7 #include <ctime>
      8 #include <vector>
      9 #include <list>
     10 #include <queue>
     11 #define M0(a) memset(a, 0, sizeof(a))
     12 #define Inf 0x7fffffff
     13 #define MXN 2110
     14 using namespace std;
     15 vector<int> edge[MXN];
     16 int dx[MXN], dy[MXN];
     17 int a[120][120];
     18 bool state[2010];
     19 int match[2010], Mx[2010];
     20 int n, m;
     21 
     22 void add(int x, int y){
     23     edge[x].push_back(y);
     24     edge[y].push_back(x); 
     25 }
     26 
     27 void init(){
     28     M0(a);
     29     int x, y;
     30     for (int i = 0; i <= n + m; ++i)
     31         edge[i].clear();
     32     for (int i = 1; i <= n; ++i){
     33          scanf("%d%d", &x, &y);
     34          a[x][y] = i;
     35          a[x + 1][y] = i;
     36     }
     37     for (int i = 1; i <= m; ++i){
     38          scanf("%d%d", &x, &y);
     39          int now = a[x][y];
     40          if (now) add(i + n, now);
     41          now = a[x][y + 1];
     42          if (now) add(i + n, now);
     43     }
     44 }
     45 
     46 bool bfs(){
     47     queue<int> q;
     48     bool flag = false;
     49     M0(dx);
     50     M0(dy);
     51     for (int i = 1; i <= n; ++i)
     52        if (!Mx[i]){
     53             q.push(i);
     54             dx[i] = 1;        
     55        } 
     56     int u, v;
     57     while (!q.empty()){
     58         u = q.front();
     59         for (int i = 0; i < edge[u].size(); ++i){
     60              v = edge[u][i];
     61              if (dy[v]) continue;
     62              dy[v] = dx[u] + 1;
     63              if (match[v] == -1) flag = true;
     64              else {
     65                      q.push(match[v]);
     66                      dx[match[v]] = dy[v] + 1;
     67                   }
     68         } 
     69         q.pop();  
     70     }
     71     return flag;
     72 }
     73 
     74 bool search_path(int u){
     75      int v;
     76      for (int i = 0; i < edge[u].size(); ++i){
     77          v = edge[u][i];
     78          if (dy[v] != dx[u] + 1) continue;
     79          if (!state[v]){
     80               state[v] = true;
     81               if (match[v] == -1 || search_path(match[v])){
     82                   Mx[u] = v;
     83                   match[v] = u;
     84                   return true;             
     85               }             
     86          }
     87      }
     88      return false;
     89 }
     90 
     91 void HK(){
     92     M0(Mx);
     93     int M = 0;
     94     memset(match, -1, sizeof(match));
     95     while (bfs()){
     96        M0(state);
     97        for (int i = 1; i <= n; ++i)
     98           if(!Mx[i] && search_path(i)) ++M;
     99     }
    100     printf("%d
    ", n + m - M);
    101 }
    102 
    103 int main(){
    104   //   freopen("hdu4619.in","r", stdin);
    105   //   freopen("hdu4619.out","w", stdout);    
    106      while (scanf("%d%d", &n, &m) != EOF){
    107          if (!n) break;
    108          init();
    109          HK();
    110      }
    111   //   fclose(stdin); fclose(stdout);
    112 }
  • 相关阅读:
    windows安全实验
    ping 命令的禁止 以及密码的攻破
    网络基础
    html 中间件
    js php BurpSuite v2.1
    网页标签,PHPstudy
    说说text_line_orientation算子的巧妙应用
    说说C#进行数字图像处理的方法
    微信张小龙产品30条
    说说几个常用的阈值分割算子
  • 原文地址:https://www.cnblogs.com/yzcstc/p/3400871.html
Copyright © 2011-2022 走看看