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

P3386 【模板】二分图匹配(匈牙利&最大流)

时间:2018-03-11 14:14:22      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:stat   cli   html   hit   close   背景   输入输出   情况   turn   

 P3386 【模板】二分图匹配

题目背景

二分图

题目描述

给定一个二分图,结点个数分别为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 的数据自觉过滤掉。

算法:二分图匹配

 

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 }
View Code

 

 

最大流

技术分享图片
 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 }
View Code

 

P3386 【模板】二分图匹配(匈牙利&最大流)

标签:stat   cli   html   hit   close   背景   输入输出   情况   turn   

原文地址:https://www.cnblogs.com/mjtcn/p/8543523.html

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