题目背景
二分图
题目描述
给定一个二分图,结点个数分别为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 的数据自觉过滤掉。
算法:二分图匹配
code
匈牙利

1 #include<cstdio>
2 #include<algorithm>
3 #include<cstring>
4 #include<cmath>
5 #include<cstdlib>
6
7 using namespace std;
8
9 const int N = 1010;
10 int e[N][N],vis[N],resut[N];
11 int n,m,E;
12
13 inline int read() {
14 int x = 0,f = 1;char ch = getchar();
15 for (; ch<'0'||ch>'9'; ch = getchar())
16 if (ch=='-') f = -1;
17 for (; ch>='0'&&ch<='9'; ch = getchar())
18 x = x*10+ch-'0';
19 return x*f;
20 }
21
22 bool dfs(int u) {
23 for (int v=1; v<=m; ++v) {
24 if (e[u][v] && !vis[v]) {
25 vis[v] = true;
26 if (!resut[v] || dfs(resut[v])) {
27 resut[v] = u;
28 return true;
29 }
30 }
31 }
32 return false;
33 }
34
35 void xyl() {
36 int ans = 0;
37 for (int i=1; i<=n; ++i) {
38 memset(vis,false,sizeof(vis));
39 if (dfs(i)) ans++;
40 }
41 printf("%d",ans);
42 }
43
44 int main() {
45 n = read(),m = read(),E = read();
46 for (int i=1; i<=E; ++i) {
47 int a = read(),b = read();
48 if (a >n || b > m) continue;
49 e[a][b] = 1;
50 }
51 xyl();
52 return 0;
53 }
更新2018-06-03

1 #include<cstdio>
2 #include<cstring>
3 #include<cctype>
4
5 const int N = 1010;
6
7 struct Edge{
8 int to,nxt;
9 Edge() {}
10 Edge(int a,int b) {to = a,nxt = b;}
11 }e[1000100];
12 int head[N],match[N],tot;
13 bool vis[N];
14 int n,m;
15
16 inline int read() {
17 int x = 0,f = 1;char ch = getchar();
18 for (; !isdigit(ch); ch=getchar()) if(ch=='-') f=-1;
19 for (; isdigit(ch); ch=getchar()) x=x*10+ch-'0';
20 return x * f;
21 }
22 bool dfs(int u) {
23 for (int i=head[u]; i; i=e[i].nxt) {
24 int v = e[i].to;
25 if (!vis[v]) {
26 vis[v] = true;
27 if (!match[v] || dfs(match[v])) {
28 match[v] = u;
29 return true;
30 }
31 }
32 }
33 return false;
34 }
35 int main () {
36 n = read(),m = read();int E = read();
37 for (int i=1; i<=E; ++i) {
38 int u = read(),v = read();
39 if (u > n || v > m) continue;
40 e[++tot] = Edge(v,head[u]);
41 head[u] = tot;
42 }
43 int ans = 0;
44 for (int i=1; i<=n; ++i) {
45 memset(vis,false,sizeof(vis));
46 if (dfs(i)) ans++;
47 }
48 printf("%d",ans);
49 return 0;
50 }
最大流

1 #include<cstdio>
2 #include<algorithm>
3 #include<cstring>
4
5 using namespace std;
6
7 const int N = 2010;
8 const int INF = 1e9;
9 struct Edge{
10 int to,nxt,c;
11 Edge() {}
12 Edge(int x,int y,int z) {to = x,c = y,nxt = z;}
13 }e[1000100];
14 int q[1000100],L,R,S,T,tot = 1;
15 int dis[N],cur[N],head[N];
16
17 inline char nc() {
18 static char buf[100000],*p1 = buf,*p2 = buf;
19 return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF :*p1++;
20 }
21 inline int read() {
22 int x = 0,f = 1;char ch=nc();
23 for (; ch<'0'||ch>'9'; ch=nc()) if(ch=='-')f=-1;
24 for (; ch>='0'&&ch<='9'; ch=nc()) x=x*10+ch-'0';
25 return x*f;
26 }
27 void add_edge(int u,int v,int c) {
28 e[++tot] = Edge(v,c,head[u]);head[u] = tot;
29 e[++tot] = Edge(u,0,head[v]);head[v] = tot;
30 }
31 bool bfs() {
32 for (int i=1; i<=T; ++i) cur[i] = head[i],dis[i] = -1;
33 L = 1,R = 0;
34 q[++R] = S;dis[S] = 1;
35 while (L <= R) {
36 int u = q[L++];
37 for (int i=head[u]; i; i=e[i].nxt) {
38 int v = e[i].to;
39 if (dis[v] == -1 && e[i].c > 0) {
40 dis[v] = dis[u]+1;q[++R] = v;
41 if (v==T) return true;
42 }
43 }
44 }
45 return false;
46 }
47 int dfs(int u,int flow) {
48 if (u==T) return flow;
49 int used = 0;
50 for (int &i=cur[u]; i; i=e[i].nxt) {
51 int v = e[i].to;
52 if (dis[v] == dis[u] + 1 && e[i].c > 0) {
53 int tmp = dfs(v,min(flow-used,e[i].c));
54 if (tmp > 0) {
55 e[i].c -= tmp;e[i^1].c += tmp;
56 used += tmp;
57 if (used == flow) break;
58 }
59 }
60 }
61 if (used != flow) dis[u] = -1;
62 return used;
63 }
64 int dinic() {
65 int ret = 0;
66 while (bfs()) ret += dfs(S,INF);
67 return ret;
68 }
69 int main() {
70 int n = read(),m = read(),E = read();
71 S = n+m+1;T = n+m+2;
72 for (int i=1; i<=E; ++i) {
73 int u = read(),v = read();
74 if (u > n || v > m) continue;
75 add_edge(u,v+n,1);
76 }
77 for (int i=1; i<=n; ++i) add_edge(S,i,1);
78 for (int i=1; i<=m; ++i) add_edge(i+n,T,1);
79 int ans = dinic();
80 printf("%d",ans);
81 return 0;
82 }
来源:https://www.cnblogs.com/mjtcn/p/8543523.html
