P3386 【模板】二分图最大匹配

https://www.luogu.com.cn/problem/P3386

题目描述

给定一个二分图,其左部点的个数为 nn,右部点的个数为 mm,边数为 ee,求其最大匹配的边数。

左部点从 11 至 nn 编号,右部点从 11 至 mm 编号。

输入格式

输入的第一行是三个整数,分别代表 nn,mm 和 ee。

接下来 ee 行,每行两个整数 u, vu,v,表示存在一条连接左部点 uu 和右部点 vv 的边。

输出格式

输出一行一个整数,代表二分图最大匹配的边数。

输入输出样例

输入 #1复制

1 1 1
1 1

输出 #1复制

1

输入 #2复制

4 2 7
3 1
1 2
3 2
1 1
4 2
4 1
1 1

输出 #2复制

2

说明/提示

数据规模与约定

对于全部的测试点,保证:

  • 1 \leq n, m \leq 5001≤n,m≤500。
  • 1 \leq e \leq 5 \times 10^41≤e≤5×104。
  • 1 \leq u \leq n1≤u≤n,1 \leq v \leq m1≤v≤m。

不保证给出的图没有重边


二分图匹配板子题。用网络流来解决就是建立两个虚拟源点,一个是起点,一个是终点,然后起点到左半部建边权1的边,终点到右半部建边权为1的边,中间建边权为1的边。最后的最大匹配就是汇入汇点的最大流。

#include
#include
#include
#include
#include
#include
#include
#include
#define debug(a) cout<<#a<<"="<e;//保存所有边的信息 
vectorg[maxn];//邻接表,g[i][j]保存节点i的第j条边在e数组里的编号 
int a[maxn];//每个点目前流经的水量
int p[maxn];//p[i]表示从原点s到终点t的节点i的前一条边的编号 

void addedge(int u,int v,int c){
	e.push_back({u,v,c,0});//正向边
	e.push_back({v,u,0,0});//反向边,容量是0
	int m=e.size();
	g[u].push_back(m-2);//正向边编号,起始号0 
	g[v].push_back(m-1); //反向边编号,起始号1 
}
LL Maxflow(int s,int t){
	LL flow=0;
	while(true){
		memset(a,0,sizeof(a));//从原点s开始放水。最初每个点的水量为0
		queueQ;
		Q.push(s);
		a[s]=INF; //原点的水设置成无穷大
		while(Q.size()){
			int x=Q.front();//取出目前水流到的节点
			Q.pop();
			for(int i=0;inow.flow){//a[i]=0表示还没流到,cap>flow说明路还没满 
					p[now.to]=g[x][i];//反向记录路径
					a[now.to]=min(a[x],now.cap-now.flow);//流到下一点的水量为上一点的水量或者路径上还可以流的最大流量,这两者取最小值
					Q.push(now.to); 
				}
			} 
			if(a[t]) break;//如果已经流到了终点t,退出本次找增广路 
		} 
		if(!a[t]) break;//如果所有路都已经试过,水不能流到终点 ,说明没有增广路,已经是最大流 
		for(int u=t;u!=s;u=e[p[u]].from)//反向记录路径
		{
			e[p[u]].flow+=a[t];//路径上所有正向边的流量增加流到终点的流量
			e[p[u]^1].flow-=a[t];//路径上所有反向边的流量减少流到终点的流量	
		} 
		flow+=a[t];//最大流加上本次流到终点的流量
	}
	return flow;	
}
int main(void)
{
  int n,m,e;//n为点数,m为边数
  scanf("%d%d%d",&n,&m,&e);
  for(int i=1;i<=n;i++) addedge(1,i+1,1);
  for(int i=n+2;i<=n+m+1;i++) addedge(i,n+m+2,1);
  for(int i=1;i<=e;i++){
  	int _x,_y,_w=1;scanf("%d%d",&_x,&_y);
  	addedge(_x+1,_y+n+1,_w);
  }
  printf("%lld\n",Maxflow(1,n+m+2));
return 0;
}

 

你可能感兴趣的:(网络流)