zoukankan      html  css  js  c++  java
  • 二分图匹配模板

    二分图匹配:

    知识点:交替路,增广路,匈牙利树,匈牙利算法求最大匹配数,bfs染色法判断是否是二分图(不存在奇数回路)

    例题:hud2063 匈牙利算法

     1 #include <iostream>
     2 #include<bits/stdc++.h>
     3 //二分图匹配,在find函数理解。
     4 //找增广路,增广路的定义是从为匹配的节点出发,终止与未匹配的节点,中间是交替路。
     5 //find函数的递归不是一层一层的,而是直接dfs一个节点的匹配的节点
     6 //然后沿着增广路修改相互匹配的节点,在寻找过程中,用vis标记节点是否在增广路中,可以保证找的路线就是交替路,
     7 #include <iostream>
     8 using namespace std;
     9 const int N = 505;
    10 vector<int>ve[2 * N];
    11 bool vis[2 * N];
    12 int match[2 * N];
    13 int k, m, n;
    14 bool find(int u) {
    15     for (int i = 0; i < ve[u].size(); i++) {
    16         int v = ve[u][i];
    17         if (!vis[v]) {//不在交替路中
    18             vis[v] = true;//放入交替路中
    19             if (match[v] == -1 || find(match[v])) {
    20                 //最后找到未匹配的点,说明找到一条增广路。
    21                 //交换路径,返回成功。
    22                 match[v] = u;
    23                 match[u] = v;
    24                 return true;
    25             }
    26         }
    27     }
    28     return false;
    29 }
    30 void count() {
    31     int ans = 0;
    32     for (int i = 1; i <=m + n; i++) {
    33         if (match[i] == -1) {
    34             memset(vis, false, sizeof(vis));
    35             if (find(i))ans++;
    36         }
    37     }
    38     cout << ans << endl;
    39 }
    40 void init() {
    41     for (int i = 0; i < 2 * N; i++) {
    42         ve[i].clear();
    43     }
    44     memset(match, -1, sizeof(match));
    45 }
    46 int main()
    47 {
    48 
    49     int u, v;
    50     while (scanf("%d", &k) && k) {
    51         scanf("%d%d", &m, &n);
    52         init();
    53         for (int i = 0; i < k; i++) {
    54             scanf("%d%d", &u, &v);
    55             ve[u].push_back(v + m);
    56             ve[v + m].push_back(u);
    57         }
    58         count();
    59     }
    60 
    61     return 0;
    62 }

    bfs染色法

    bool bfs()
    {
        queue<int> q;
        bool tag[N];
        //memset(tag,false,sizeof(tag));
        memset(vis,false,sizeof(vis));
        for (int j=1;j<=n;j++) if (!vis[j]) { // 遇到没染色的点就从它出发去染色其它点
            q.push(j);
            tag[j]= vis[j]=true;
            while(!q.empty()){
                int t=q.front();  q.pop();
                for (int i=1;i<=n;i++) if (g[t][i] && i!=t)
                {
                    if (vis[i]){
                        if (tag[i]==tag[t]) return false;
                    } else{
                       tag[i]=!tag[t];
                       q.push(i);
                       vis[i]=true;
                    }
                }
            }
        }
    
        return true;
    }
    不疯魔不成活
  • 相关阅读:
    JAVA学习25天
    Java学习第24天
    Java学习第23天
    Java学习22天
    第3周
    Java21
    day23作业
    day23
    Typecho使用技巧
    搭建Typecho博客
  • 原文地址:https://www.cnblogs.com/gzr2018/p/10823647.html
Copyright © 2011-2022 走看看