zoukankan      html  css  js  c++  java
  • hungary HK 多重匹配

     1 /*Author :usedrose  */
     2 /*Created Time :2015/8/1 23:39:01*/
     3 /*File Name :2.cpp*/
     4 #pragma comment(linker, "/STACK:1024000000,1024000000") 
     5 #include <cstdio>
     6 #include <iostream>
     7 #include <algorithm>
     8 #include <sstream>
     9 #include <cstdlib>
    10 #include <cstring>
    11 #include <climits>
    12 #include <vector>
    13 #include <string>
    14 #include <ctime>
    15 #include <cmath>
    16 #include <deque>
    17 #include <queue>
    18 #include <stack>
    19 #include <set>
    20 #include <map>
    21 #define INF 0x3f3f3f3f
    22 #define eps 1e-8
    23 #define pi acos(-1.0)
    24 #define MAXN 5010
    25 #define MAXM 50010
    26 #define OK cout << "ok" << endl;
    27 #define o(a) cout << #a << " = " << a << endl
    28 #define o1(a,b) cout << #a << " = " << a << "  " << #b << " = " << b << endl
    29 using namespace std;
    30 typedef long long LL;
    31 
    32 struct Edge{
    33     int to, next;
    34 }edge[MAXM];
    35 int head[MAXM], tot;
    36 
    37 void init()
    38 {
    39     tot = 0;
    40     memset(head, -1, sizeof(head));
    41 }
    42 
    43 void addedge(int u, int v)
    44 {
    45     edge[tot].to = v;
    46     edge[tot].next = head[u];
    47     head[u] = tot++;
    48 }
    49 
    50 int linker[MAXN];
    51 bool used[MAXN];
    52 int uN;
    53 
    54 bool dfs(int u)
    55 {
    56     for (int i = head[u]; i != -1; i = edge[i].next) {
    57         int v = edge[i].to;
    58         if (!used[v]) {
    59             used[v] = true;
    60             if (linker[v] == -1 || dfs(linker[v])) {
    61                 linker[v] = u;
    62                 return true;
    63             }
    64         }
    65     }
    66     return false;
    67 }
    68 
    69 int hungary()
    70 {
    71     int res = 0;
    72     memset(linker, -1, sizeof(linker));
    73     for (int u = 0;u < uN;++ u) {
    74         memset(used, false, sizeof(used));
    75         if (dfs(u)) res++;
    76     }
    77     return res;
    78 }
    79 
    80 
    81 int main()
    82 {
    83     while (~scanf("%d", &uN)) {
    84         init();
    85         int a, b, c;
    86         for (int i = 0;i < uN; ++ i) {
    87             scanf("%d: (%d)", &a, &b);
    88             for (int j = 0;j < b; ++ j) {
    89                 scanf("%d", &c);
    90                 addedge(a, c);
    91             }
    92         }
    93         printf("%d
    ", uN - hungary()/2);
    94     }
    95     return 0;
    96 }
    View Code

    HK模板

      1 /*Author :usedrose  */
      2 /*Created Time :2015/8/3 14:55:13*/
      3 /*File Name :2.cpp*/
      4 #pragma comment(linker, "/STACK:1024000000,1024000000") 
      5 #include <cstdio>
      6 #include <iostream>
      7 #include <algorithm>
      8 #include <sstream>
      9 #include <cstdlib>
     10 #include <cstring>
     11 #include <climits>
     12 #include <vector>
     13 #include <string>
     14 #include <ctime>
     15 #include <cmath>
     16 #include <deque>
     17 #include <queue>
     18 #include <stack>
     19 #include <set>
     20 #include <map>
     21 #define INF 0x3f3f3f3f
     22 #define eps 1e-8
     23 #define pi acos(-1.0)
     24 #define MAXN 3010
     25 #define MAXM 100110
     26 #define OK cout << "ok" << endl;
     27 #define o(a) cout << #a << " = " << a << endl
     28 #define o1(a,b) cout << #a << " = " << a << "  " << #b << " = " << b << endl
     29 using namespace std;
     30 typedef long long LL;
     31 
     32 
     33 vector<int> G[MAXN];
     34 int uN;
     35 int Mx[MAXN], My[MAXN];
     36 int dx[MAXN], dy[MAXN];
     37 int dis;
     38 bool used[MAXN];
     39 
     40 bool SearchP()
     41 {
     42     queue<int> Q;
     43     dis = INF;
     44     memset(dx, -1, sizeof(dx));
     45     memset(dy, -1, sizeof(dy));
     46     for (int i = 0;i < uN; ++ i) 
     47         if (Mx[i] == -1) {
     48             Q.push(i);
     49             dx[i] = 0;
     50         }
     51     while (!Q.empty()) {
     52         int u = Q.front();
     53         Q.pop();
     54         if (dx[u] > dis) break;
     55         int sz = G[u].size();
     56         for (int i = 0;i < sz; ++ i) {
     57             int v = G[u][i];
     58             if (dy[v] == -1) {
     59                 dy[v] = dx[u] + 1;
     60                 if (My[v] == -1) dis = dy[v];
     61                 else {
     62                     dx[My[v]] = dy[v] + 1;
     63                     Q.push(My[v]);
     64                 }
     65             }
     66         }
     67     }
     68     return dis != INF;
     69 }
     70 
     71 bool DFS(int u)
     72 {
     73     int sz = G[u].size();
     74     for (int i = 0;i < sz; ++ i) {
     75         int v = G[u][i];
     76         if (!used[v] && dy[v] == dx[u] + 1) {
     77             used[v] = true;
     78             if (My[v] != -1 && dy[v] == dis) continue;
     79             if (My[v] == -1 || DFS(My[v])) {
     80                 My[v] = u;
     81                 Mx[u] = v;
     82                 return true;
     83             }
     84         }
     85     }
     86     return false;
     87 }
     88 
     89 int MaxMatch()
     90 {
     91     int res = 0;
     92     memset(Mx, -1, sizeof(Mx));
     93     memset(My, -1, sizeof(My));
     94     while (SearchP()) {
     95         memset(used, false, sizeof(used));
     96         for (int i = 0;i < uN; ++ i)
     97             if (Mx[i] == -1 && DFS(i))
     98                 res++;
     99     }
    100     return res;
    101 }
    102 
    103 int T, k;
    104 int t, n, m;
    105 int x[MAXN], y[MAXN], s[MAXN];
    106 
    107 int main()
    108 {
    109     //freopen("data.in","r",stdin);
    110     //freopen("data.out","w",stdout);
    111     cin.tie(0);
    112     ios::sync_with_stdio(false);
    113     cin >> T;
    114     while (T--) {
    115         cin >> t;
    116         cin >> m;
    117         for (int i = 0;i < m; ++ i) 
    118             cin >> x[i] >> y[i] >> s[i];
    119         cin >> uN;
    120         for (int i = 0;i <= uN; ++ i) {
    121             G[i].clear();
    122         }
    123         int a, b;
    124         for (int i = 0;i < uN; ++ i) {
    125             cin >> a >> b;
    126             for (int j = 0;j < m; ++ j) {
    127                 if (sqrt((a-x[j])*(a-x[j]) + (b-y[j])*(b-y[j])) <= t*s[j]) {
    128                     //G[j].push_back(i);
    129                     G[i].push_back(j);
    130                 }
    131             }
    132         }        
    133         cout << "Scenario #" << ++k << ":" << endl;
    134         cout << MaxMatch() << endl << endl;
    135     }
    136     return 0;
    137 }
    View Code

    多重匹配模板

    hdu 3605

    http://www.cppblog.com/JulyRina/archive/2015/02/13/209816.html

    题目大意:有N(N<100,000)个人要去M(M<10)个星球,每个人只可以去一些星球,一个星球最多容纳Ki个人。请问是否所有人都可以选择自己的星球
     
    题目分析;直接建立二分图模型,使用匈牙利算法。
        匈牙利算法可以解决多重匹配,原理和二分图最大匹配很像。注意不要把可以匹配多个的点分割然后按照正常的二分匹配来做,那样肯定会挂的。
        解决多重匹配就是记录一下多重匹配的点(简称Y方点)已经匹配了Pi个点。如果Pi<Ki那么就直接上了,否则的话继续搜索Yi已经匹配的每一个点并将Yi染色。
        因为Yi搜一次就需要染色了,而且Y方点最多是10个,所以每次找增广路的深度最多是10,这样就很快了。
     
     1 /*Author :usedrose  */
     2 /*Created Time :2015/8/3 18:48:30*/
     3 /*File Name :2.cpp*/
     4 #pragma comment(linker, "/STACK:1024000000,1024000000") 
     5 #include <cstdio>
     6 #include <iostream>
     7 #include <algorithm>
     8 #include <sstream>
     9 #include <cstdlib>
    10 #include <cstring>
    11 #include <climits>
    12 #include <vector>
    13 #include <string>
    14 #include <ctime>
    15 #include <cmath>
    16 #include <deque>
    17 #include <queue>
    18 #include <stack>
    19 #include <set>
    20 #include <map>
    21 #define INF 0x3f3f3f3f
    22 #define eps 1e-8
    23 #define pi acos(-1.0)
    24 #define MAXN 100010
    25 #define MAXM 11
    26 #define OK cout << "ok" << endl;
    27 #define o(a) cout << #a << " = " << a << endl
    28 #define o1(a,b) cout << #a << " = " << a << "  " << #b << " = " << b << endl
    29 using namespace std;
    30 typedef long long LL;
    31 
    32 int n, m;
    33 int stk[MAXM][MAXN], top[MAXM], Maxpeo[MAXM];
    34 bool G[MAXN][MAXM];
    35 bool T[MAXM];
    36 
    37 //适用于正整数
    38 template <class T>
    39 inline void scan_d(T &ret) {
    40     char c; ret=0;
    41     while((c=getchar())<'0'||c>'9');
    42     while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();
    43 }
    44 
    45 bool dfs(int u)
    46 {
    47     for (int i = 1;i <= m; ++ i) 
    48         if (G[u][i] && !T[i]) {
    49             T[i] = true;
    50             if (top[i] < Maxpeo[i]) {//如果该星球未注满 直接匹配
    51                 stk[i][top[i]++] = u;
    52                 return true;
    53             }
    54             for (int j = 0;j < top[i]; ++ j) //否则
    55                 if (dfs(stk[i][j])) {        //将已经匹配的点寻找其他可行匹配
    56                     stk[i][j] = u;
    57                     return true;
    58                 }
    59         }
    60     return false;
    61 }
    62 
    63 bool solve()
    64 {
    65     memset(top, 0, sizeof(top));
    66     for (int i = 1;i <= n; ++ i) {
    67         memset(T, 0, sizeof(T));
    68         if (!dfs(i)) return false;
    69     }
    70     return true;
    71 }
    72 
    73 void input()
    74 {
    75     for (int i = 1;i <= n; ++ i)
    76         for (int j = 1;j <= m; ++ j) 
    77             scan_d(G[i][j]);
    78     for (int i = 1;i <= m; ++ i)
    79         scan_d(Maxpeo[i]);
    80 }
    81 
    82 int main()
    83 {
    84     while (~scanf("%d%d", &n, &m)) {
    85         input();
    86         if (solve()) puts("YES");
    87         else puts("NO");
    88     }
    89     return 0;
    90 }
    View Code
  • 相关阅读:
    对称加密算法在C#中的踩坑日常
    php与Git下基于webhook的自动化部署
    1024程序员节阿里谜题解析
    一次ajax请求导致status为canceled的原因小记
    LigerUI下拉选择列表LigerComboBox中tree的节点初始化默认选中的问题
    linux环境下安装PHP扩展swoole
    Memcache PHP 使用笔记
    VS生成事件执行XCOPY时出现Invalid num of parameters的解决方案
    mysql表的完整性约束
    mysql支持的数据类型
  • 原文地址:https://www.cnblogs.com/usedrosee/p/4694940.html
Copyright © 2011-2022 走看看