码迷,mamicode.com
首页 > 其他好文 > 详细

二分图板子

时间:2020-07-14 21:42:51      阅读:67      评论:0      收藏:0      [点我收藏+]

标签:km算法   main   printf   eof   getch   std   bit   tag   empty   

二分图最大匹配:

匈牙利算法  邻接表O(mn):

技术图片
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;

const int maxn = 1010;
const int maxm = 2e5;
int n, m, t;
int mch[maxn], vistime[maxn];

struct E {
    int to, next;
}edge[maxm];

int tot, head[maxn];

void init()
{
    memset(vistime, 0, sizeof(vistime));
    memset(head, -1, sizeof(head));
    tot = 0;
}

inline void add_edge(int u, int v) {
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot++;
}

bool Hungarian(int u, int tag) {
    if (vistime[u] == tag) return 0;
    vistime[u] = tag;
    for (int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].to;
        if ((mch[v] == 0) || Hungarian(mch[v], tag)) {
            mch[v] = u;
            return 1;
        }
    }
    return 0;
}

int main() {
    scanf("%d%d%d", &n, &m, &t);
    init();
    while (t--) {
        int u, v;
        scanf("%d%d", &u, &v);
        add_edge(u, v);
    }
    int ans = 0;
    for (int i = 1; i <= n; ++ i)
        if (Hungarian(i, i))
            ++ans;
    printf("%d\n", ans);
    return 0;
}
View Code

KM算法  O(N^3):

技术图片
#include <bits/stdc++.h>
using namespace std;

const int maxn = 501;
const int maxm = 250001;
const int inf = 0x3f3f3f3f;

int nl, nr, m;
int tot, head[maxn];
int ans, linkx[maxn], linky[maxn];
int dx[maxn], dy[maxn];

struct E {
    int to, next;
}edge[maxm]; //这里千万要注意,如果题目是双向边的话,这里的N要开2*N

inline void read(int& ans)
{
    int x = 0, f = 1;
    char ch = getchar();
    while (ch<0 || ch > 9) {
        if (ch == -) f = -1;
        ch = getchar();
    }
    while ( ch >= 0 && ch <= 9) {
        x = x * 10 + ch - 0;
        ch = getchar();
    }
    ans =  x * f;
}
//加边
inline void add_edge(int u, int v) {
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot++;
    if (!linkx[u] && !linky[v])
        linky[v] = u, linkx[u] = v, ++ ans;
}

bool bfs()
{
    bool ret=0;
    queue<int> q;
    memset(dx, 0, sizeof(dx)), memset(dy, 0, sizeof(dy));
    for (int i = 1; i <= nl; ++ i)
        if (!linkx[i]) q.push(i);
    while (!q.empty()) {
        int u = q.front(); q.pop();
        for (int i = head[u]; ~i; i = edge[i].next) {
            int v = edge[i].to;
            if (!dy[v]) {
                dy[v] = dx[u] + 1;
                if (!linky[v]) ret = 1;
                else dx[linky[v]] = dy[v]+1, q.push(linky[v]);
            }
        }
    }
    return ret;
}

bool dfs(int u)
{
    for (int i = head[u]; ~i; i = edge[i].next) {
        int v = edge[i].to;
        if (dy[v] == dx[u] + 1) {
            dy[v] = 0;
            if (!linky[v] || dfs(linky[v])) {
                linky[v] = u, linkx[u] = v;
                return 1;
            }
        }
    }
    return 0;
}

int main()
{
    int a, b;
    memset(head, -1, sizeof(head));
    read(nl), read(nr), read(m);
    for (int i = 1; i <= m; ++ i)
        read(a), read(b), add_edge(a,b);

    while(bfs()) {
        for (int i = 1; i <= nl; ++ i)
            if (!linkx[i] && dfs(i))
                ++ ans;
    }

    printf("%d\n",ans);
//  这段循环是用来输出跟谁匹配 
//    for (int i = 1; i <= nl; ++ i)
//        printf("%d ",linkx[i]);

    return 0;
}
View Code

 

二分图板子

标签:km算法   main   printf   eof   getch   std   bit   tag   empty   

原文地址:https://www.cnblogs.com/Vikyanite/p/13301178.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!