博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P3386 【模板】二分图匹配(匈牙利&最大流)
阅读量:4615 次
发布时间:2019-06-09

本文共 5138 字,大约阅读时间需要 17 分钟。

 P3386 【模板】二分图匹配

题目背景

二分图

题目描述

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

输入输出格式

输入格式:

 

第一行,n,m,e

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

 

输出格式:

 

共一行,二分图最大匹配

 

输入输出样例

输入样例#1: 
1 1 11 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
2 #include
3 #include
4 #include
5 #include
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

 

更新2018-06-03

1 #include
2 #include
3 #include
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 }
View Code

 

 

最大流

1 #include
2 #include
3 #include
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

 

转载于:https://www.cnblogs.com/mjtcn/p/8543523.html

你可能感兴趣的文章
关于u32中查找和定位最后到bit Number of 1 Bits
查看>>
sql数据库查询
查看>>
云计算技能图谱
查看>>
类的方法
查看>>
数据结构(栈&堆 )
查看>>
Oracle 高级分组
查看>>
IDEA-常用快捷键
查看>>
有道显示网络已断开
查看>>
Python9-进程池-day38
查看>>
进程的状态(转)
查看>>
spring mvc为何多注入了个SimpleUrlHandlerMapping?
查看>>
node express框架基本配置
查看>>
深入理解MySQL的ACID四大特性原理
查看>>
Codeforces Round #463 F. Escape Through Leaf (李超线段树合并)
查看>>
@ResponseBody 注解是什么意思?
查看>>
Code4App地址
查看>>
蓄水池抽样
查看>>
C#与数据库访问技术总结(十五)之 DataAdapter对象代码示例
查看>>
Sublime Text 插件推荐——for web developers
查看>>
Grails中service的线程安全的小例子
查看>>