洛谷P3386 :【模板】二分图匹配
https://www.luogu.org/problemnew/show/P3386
题目描述
给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数
输入输出格式
输入格式:
第一行,n,m,e
第二至e+1行,每行两个正整数u,v,表示u,v有一条连边
输出格式:
共一行,二分图最大匹配
输入输出样例
输入样例#1: 复制
1 1 1
1 1
输出样例#1: 复制
1
说明
n,m≤1000 , 1≤u≤n , 1≤v≤m,e≤n×m
因为数据有坑,可能会遇到 v>m 或者 u>n 的情况。请把 v>m 或者 u>n的数据自觉过滤掉。
算法:二分图匹配
未用邻接表:
#include <stdio.h>
#include <string.h>
using namespace std;
#define N 1020
int e[N][N];
int book[N], l[N], n, m;
int dfs(int s)
{
int i, len, j;
for(i=1; i<=m; i++)
{
if(book[i]==0 && e[s][i])
{
book[i]=1;
if(l[i]==0 || dfs(l[i]))
{
l[i]=s;
return 1;
}
}
}
return 0;
}
int main()
{
int i, j, u, v, ans, w;
scanf("%d%d%d", &n, &m, &w);
for(i=0; i<w; i++)
{
scanf("%d%d", &u, &v);
if(u>n || v>m)
continue;
e[u][v]=1;
}
ans=0;
for(i=1; i<=n; i++)
{
memset(book, 0, sizeof(book));
if(dfs(i))
ans++;
}
printf("%d\n", ans);
return 0;
}
邻接表写法:
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
#define N 1020
vector<int>e[N];
int book[N], l[N];
int dfs(int s)
{
int i, len, j, x;
len=e[s].size();
for(i=0; i<len; i++)
{
x=e[s][i];
if(book[x]==0)
{
book[x]=1;
if(l[x]==0 || dfs(l[x]))
{
l[x]=s;
return 1;
}
}
}
return 0;
}
int main()
{
int n, m, i, j, u, v, ans, w;
scanf("%d%d%d", &n, &m, &w);
memset(l, 0, sizeof(l));
for(i=0; i<w; i++)
{
scanf("%d%d", &u, &v);
if(u>n || v>m)
continue;
e[u].push_back(v);
}
ans=0;
for(i=1; i<=n; i++)
{
memset(book, 0, sizeof(book));
if(dfs(i))
ans++;
}
printf("%d\n", ans);
return 0;
}
网络最大流:
#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>
using namespace std;
#define N 2020
int book[N], l[N], n, m, inf=99999999;
struct edge{
int to;
int cap;
int rev;
};
vector<edge>G[N];
void add (int from, int to)
{
int cap=1;
G[from].push_back((edge){to, cap, G[to].size()});
G[to].push_back((edge){from, 0, G[from].size()-1});
}
int dfs(int v, int t, int f)
{
int i;
if(v==t)
return f;
book[v]=1;
for(i=0; i<G[v].size(); i++)
{
edge &e=G[v][i];
if(!book[e.to] && e.cap>0){
int d=dfs(e.to, t, min(f, e.cap));
if(d>0)
{
//G[v][i].cap-=d;
e.cap-=d;
G[e.to][e.rev].cap+=d;
return d;
}
}
}
return 0;
}
int max_flow(int s, int t)
{
int flow=0;
while(1)
//for(;;)
{
memset(book, 0, sizeof(book));
int f=dfs(s, t, inf);
if(f==0)
return flow;
flow+=f;
}
}
int main()
{
int i, u, v, s;
scanf("%d%d%d", &n, &m, &s);
for(i=1; i<=n; i++)
add(0,i);
for(i=n+1; i<=n+m; i++)
add(i, m+n+1);
while(s--)
{
scanf("%d%d", &u, &v);
if(v>m || u>n)
continue;
add(u, v+n);
}
printf("%d\n", max_flow(0, n+m+1));
return 0;
}