求调
#include<bits/stdc++.h>
using namespace std;
const int maxn=1002005;
const int maxm=2005;
const int inf=0x7fffffff;
int maxflow=0,top=1,dep[maxm],head[maxm],cur[maxm],n,m,en,s,t;
bool inq[maxm],flag[maxm][maxm],vis;
struct edgetype{
int v,w,nxt;
}e[maxn<<1];
inline void add(int u,int v,int val)
{
e[++top].v=v;
e[top].w=val;
e[top].nxt=head[u];
head[u]=top;
}
bool bfs()
{
for(int i=0;i<=maxm;++i)
{
inq[i]=0;
dep[i]=0x3f3f3f3f;
cur[i]=head[i];
}
dep[s]=0;
queue<int> q;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
inq[u]=0;
for(int i=head[u];i;i=e[i].nxt)
{
int d=e[i].v;
if(dep[d]>dep[u]+1&&e[i].w)
{
dep[d]=dep[u]+1;
if(!inq[d])
{
q.push(d);
inq[d]=1;
}
}
}
}
return dep[t]!=0x3f3f3f3f?1:0;
}
int dfs(int u,int flow)
{
if(u==t)
{
vis=1;
maxflow+=flow;
return flow;
}
int used=0,rlow=0;
for(int i=cur[u];i;i=e[i].nxt)
{
cur[u]=i;
int d=e[i].v;
if(dep[d]==dep[u]+1&&e[i].w)
{
rlow=dfs(d,min(flow-used,e[i].w));
if(rlow)
{
used+=rlow;
e[i].w-=rlow;
e[i^1].w+=rlow;
if(used==flow) break;
}
}
}
return used;
}
void dinic()
{
while(bfs())
{
dfs(s,inf);
}
}
int main()
{
scanf("%d%d%d",&n,&m,&en);
s=1,t=n+m+2;
for(int i=1,a,b;i<=en;++i)
{
scanf("%d%d",&a,&b);
if(!flag[a][b])
{
add(a+1,b+n+1,1);
add(b+n+1,a+1,0);
flag[a][b]=1;
}
}
for(int i=1;i<=n;++i)
{
add(s,i+1,1);
add(i+1,s,0);
}
for(int i=1;i<=m;++i)
{
add(i+n+1,t,1);
add(t,i+n+1,0);
}
dinic();
printf("%d",maxflow);
return 0;
}