网络流解二分图;
上代码
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int N = 2005;
const int M = 1002005;
const int INF = 0x7fffffff;
struct Edge
{
int v,val,nxt,rev;
};
Edge e[M<<1];
int fe[N];
queue<int> q;
int dep[N];
int n,m,s,t;
bool bfs()
{
while(!q.empty()) q.pop();
memset(dep,0,sizeof(dep));
q.push(s); dep[s] = 1;
while(!q.empty())
{
int c = q.front(); q.pop();
for(int i=fe[c]; i; i=e[i].nxt)
{
if(e[i].val>0 && !dep[e[i].v])
{
dep[e[i].v] = dep[c]+1;
q.push(e[i].v);
}
}
}
if(dep[t]) return true;
else return false;
}
int dfs(int pos,int cur)
{
if(pos==t) return cur;
int rst = cur;
for(int i=fe[pos]; i; i=e[i].nxt)
{
if(dep[e[i].v]==dep[pos]+1 && e[i].val>0 && rst)
{
int flow = dfs(e[i].v,min(e[i].val,rst));
if(flow>0)
{
e[i].val -= flow;
rst -= flow;
e[e[i].rev].val += flow;
}
}
}
return cur-rst;
}
int dinic()
{
int ans = 0;
while(bfs()) ans += dfs(s,INF);
return ans;
}
void addedge(int u,int v,int val,int rev)
{
e[++m].v = v; e[m].val = val; e[m].rev = rev;
e[m].nxt = fe[u]; fe[u] = m;
}
int main()
{
int n1,n2,m0; m = 0;
scanf("%d%d%d",&n1,&n2,&m0);
n = n1+n2+2;
for(int i=1; i<=m0; i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(x<=n1 && y<=n2)
{
addedge(x+1,y+n1+1,1,m+2);
addedge(y+n1+1,x+1,0,m);
}
}
for(int i=1; i<=n1; i++)
{
addedge(1,i+1,1,m+2);
addedge(i+1,1,0,m);
}
for(int i=1; i<=n2; i++)
{
addedge(i+n1+1,n,1,m+2);
addedge(n,i+n1+1,0,m);
}
s = 1; t = n;
printf("%d\n",dinic());
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define inf 2147483647
using namespace std;
struct Edge
{
int to;
int s;
int last;
}e[2001000];
int dep[4100],in[4100],cnt;
int s=0,t;
void addedge(int x,int y,int z)
{
e[++cnt].last=in[x];
e[cnt].s=z;
e[cnt].to=y;
in[x]=cnt;
}
bool bfs()
{
memset(dep,0,sizeof(dep));
queue<int> que;
que.push(s);dep[s]=1;
while(!que.empty())
{
int u=que.front();que.pop();
for(int i=in[u];i>=0;i=e[i].last)
{
if(!dep[e[i].to]&&e[i].s>0)
{
dep[e[i].to]=dep[u]+1;
que.push(e[i].to);
}
}
}
if(dep[t]) return true;
else return false;
}
int dfs(int now,int cur)
{
if(now==t) return cur;
for(int i=in[now];i>=0;i=e[i].last)
{
if(dep[e[i].to]==dep[now]+1&&e[i].s>0)
{
int flow=dfs(e[i].to,min(cur,e[i].s));
if(flow)
{
e[i].s-=flow;
if(i&1) e[i+1].s+=flow;
else e[i-1].s+=flow;
return flow;
}
}
}
return 0;
}
int main()
{
int n,m,e,i,l,x,y,ans=0;
memset(in,-1,sizeof(in));
scanf("%d%d%d",&n,&m,&e);t=n+m+1;
for(i=1;i<=n;i++){addedge(0,i,1);addedge(i,0,0);}
for(i=n+1;i<=n+m;i++){addedge(i,t,1);addedge(t,i,0);}
for(i=1;i<=e;i++)
{
scanf("%d%d",&x,&y);if(x>n||y>m) continue;
addedge(x,y+n,1);addedge(y+n,x,0);
}
while(bfs())
{
while(l=dfs(s,inf))
ans+=l;
}
printf("%d",ans);
return 0;
}