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

P3386 【模板】二分图匹配

时间:2017-11-06 19:18:18      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:names   bsp   tchar   clu   int   ring   otto   ini   lin   

题目背景

二分图

题目描述

给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数

输入输出格式

输入格式:

 

第一行,n,m,e

第二至e+1行,每行两个正整数u,v,表示u,v有一条连边

 

输出格式:

 

共一行,二分图最大匹配

 

输入输出样例

输入样例#1: 复制
1 1 1
1 1
输出样例#1: 复制
1

说明

n,m \leq 1000n,m1000, 1 \leq u \leq n1un, 1 \leq v \leq m1vm

因为数据有坑,可能会遇到 v>mv>m 的情况。请把 v>mv>m 的数据自觉过滤掉。

算法:二分图匹配

 

不知为啥,跑的真慢

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>

using namespace std;
const int N = 2010;

#define oo 99999999

int n, m, S, T, now;
int dis[N], head[N];
bool vis[N];
struct Node{
    int u, v, nxt, cap;
}E[N * N];
queue <int> Q;

inline int read(){
    int x = 0; char c = getchar();
    while(c < 0 || c > 9) c = getchar();
    while(c >= 0 && c <= 9) x = x * 10 + c - 0, c = getchar();
    return x;
}

inline void add(int u, int v, int w){
    E[now].u = u;
    E[now].v = v;
    E[now].cap = w;
    E[now].nxt = head[u];
    head[u] = now ++;
}

inline bool bfs(int start){
    for(int i = S; i <= T; i ++) dis[i] = -1;
    dis[start] = 0;
    Q.push(start);
    while(!Q.empty()){
        int topp = Q.front();
        Q.pop();
        vis[topp] = 0;
        for(int i = head[topp]; ~ i; i = E[i].nxt){
            int v = E[i].v; //cout << v <<" ";
            if(dis[v] == -1 && E[i].cap > 0){
                dis[v] = dis[topp] + 1;
                if(!vis[v]){
                    vis[v] = 1;
                    Q.push(v);
                }
            }
        }
    }
    return dis[T] != -1;
}

int dfs(int now, int minn){
    if(now == T || minn <= 0) return minn;
    int retflow = 0;
    for(int i = head[now]; ~ i; i = E[i].nxt){
        int v = E[i].v;
        if(dis[v] == dis[now] + 1 && E[i].cap){
            int f = dfs(v, min(minn, E[i].cap));
            retflow += f;
            E[i].cap -= f;
            E[i ^ 1].cap += f;
            minn -= f;
            if(minn <= 0) break;
        }
    }
    return retflow;
}
inline void Dinic(){
    int answer = 0;
    while(bfs(S)) 
        answer += dfs(S, oo);
    printf("%d", answer);
}

int main()
{
    //freopen("gg.in", "r", stdin);
    n = read();
    m = read();
    int z = read();
    int a, b;
    S = 0, T = n + m + 1;
    for(int i = S; i <= T; i ++) head[i] = -1;
    for(int i = 1; i <= z; i ++){
        int u = read();
        int v = read();
        if(v > m) continue ;
        add(u, v + n, 1); add(v + n, u, 0);
    }
    for(int i = 1; i <= n; i ++) add(S, i, 1), add(i, S, 0);
    for(int i = n + 1; i <= n + m; i ++) add(i, T, 1), add(T, i, 0);
    Dinic();
    return 0;
}
/*
1 1 
1 1 1 
*/

 

P3386 【模板】二分图匹配

标签:names   bsp   tchar   clu   int   ring   otto   ini   lin   

原文地址:http://www.cnblogs.com/lyqlyq/p/7794467.html

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