P3386 【模板】二分图匹配
题目背景
二分图
题目描述
给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数
输入输出格式
输入格式:
第一行,n,m,e
第二至e+1行,每行两个正整数u,v,表示u,v有一条连边
输出格式:
共一行,二分图最大匹配
输入输出样例
说明
n,m \leq 1000n,m≤1000, 1 \leq u \leq n1≤u≤n, 1 \leq v \leq m1≤v≤m
因为数据有坑,可能会遇到 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 */