二分图匹配(匈牙利, 最大流)

匈牙利

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
const double pi = acos(-1);
const int maxn = 1e4 + 10;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
int cnt, m, n, s, t, k;
int head[maxn], vis[maxn], match[maxn];
struct node{
    int to;
    int next;
}edge[maxm << 1];
struct nod{int x, y;}ans[maxn];
void add(int u, int v){
    edge[cnt].to = v;
    edge[cnt].next = head[u];
    head[u] = cnt ++;
}
bool dfs(int u){
    for(int i = head[u] ; i != -1 ; i = edge[i].next){
        int v = edge[i].to;
        if(!vis[v]){
            vis[v] = 1;
            if(!match[v] || dfs(match[v])){
                match[u] = v;
                match[v] = u;
                return true;
            }
        }
    }
    return false;
}
int main()
{
    int u, v;
    scanf("%d %d", &m, &n);
    memset(head, -1, sizeof(head));
    while(scanf("%d %d", &u, &v) && (u != -1 && v != -1)){
        v += m;
        add(u, v); add(v, u);
    }
    for(int i = 1 ; i <= m ; ++ i){
        memset(vis, 0, sizeof(vis));
        //puts("44");
        if(dfs(i)){
            ans[++k].x = i; ans[k].y = match[i];
        }
    }
    cout << k << endl;
    for(int i = 1 ; i <= k ; ++ i){
        cout << ans[i].x << ' ' << match[ans[i].x] - m << endl;
    }
    return 0;
}

ek最大流

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
const double pi = acos(-1);
const int maxn = 1e4 + 10;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
int m, n, s = 10000, t = 10001, cnt;
int head[maxn], vis[maxn], match[maxn];
struct node{
    int to;
    int quan;
    int next;
}edge[maxn << 1];
struct nod{
    int uu;
    int eg;
}pre[maxn];
void add(int u, int v, int w){
    edge[cnt].to = v;
    edge[cnt].quan = w;
    edge[cnt].next = head[u];
    head[u] = cnt ++;
}
bool bfs(){
    queue<int> que;
    memset(vis, 0, sizeof(vis));
    que.push(s);
    vis[s] = 1;
    while(!que.empty()){
        int u = que.front();
        que.pop();
        for(int i = head[u] ; i != -1 ; i = edge[i].next){
            int v = edge[i].to;
            if(!vis[v] && edge[i].quan){
                pre[v].uu = u;
                pre[v].eg = i;
                if(v == t) return true;
                vis[v] = 1;
                que.push(v);
            }
        }
    }
    return false;
}
int main()
{
    int u, v;
    scanf("%d %d", &m, &n);
    memset(head, -1, sizeof(head));
    for(int i = 1 ; i <= m ; ++ i) add(s, i, 1), add(i, s, 0);
    for(int i = 1 ; i <= n ; ++ i) add(i + m, t, 1), add(t, i + m, 0);
    while(scanf("%d %d", &u, &v) && (u != -1 && v != -1)){
        v += m;
        add(u, v, 1); add(v, u, 0);
    }
    int ans = 0;
    while(bfs()){
        int mini = INF;
        for(int i = t ; i != s ; i = pre[i].uu){
            mini = min(mini, edge[pre[i].eg].quan);
        }
        for(int i = t ; i != s ; i = pre[i].uu){
            match[pre[i].uu] = i;
            edge[pre[i].eg].quan -= mini;
            edge[pre[i].eg^1].quan += mini;
        }
        ans += mini;
    }
    printf("%d\n", ans);
    for(int i = 1 ; i <= m ; ++ i){
        if(match[i]) cout << i << ' ' << match[i] - m << '\n';
    }
    return 0;
}

你可能感兴趣的:(二分图匹配(匈牙利, 最大流))