建图:
源点s=0,汇点t=n+m+1
s到A的容量为1
B到t的容量为1
当a∈{A},b∈{B},a*b!=0时,a->b的容量为1
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stack>
#include<queue>
#include<math.h>
#include<cstdio>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn = 500;
const int inf = 0x7fffff;
int dist[maxn];
int pre[maxn];
int minf[maxn];
int flow[maxn][maxn];
int c[maxn][maxn];
bool vis[maxn];
int maxflow(int s,int t)
{
int f,u;
queue<int> q;
mem(flow,0);
f=0;
while(1)
{
q.push(s);
mem(vis,0);
mem(minf,0);
vis[s]=1;
minf[s]=inf;
while(!q.empty())
{
u=q.front();
q.pop();
for(int i=0;i<=t;i++)
{
if(!vis[i] && c[u][i]-flow[u][i]>0)
{
vis[i]=1;
minf[i]=min(minf[u],c[u][i]-flow[u][i]);
q.push(i);
pre[i]=u;
}
}
}
f+=minf[t];
if(minf[t]==0) break;
for(int i=t;i!=s;i=pre[i])
{
flow[i][pre[i]] -= minf[t];
flow[pre[i]][i] += minf[t];
}
}
return f;
}
int main()
{
int n,m,k,s,t,a,x,y;
while(~scanf("%d",&n))
{
if(n==0) break;
scanf("%d%d",&m,&k);
s=0;
t=n+m+1;
mem(c,0);
for(int i=1;i<=n;i++)
c[s][i]=1;
for(int i=n+1;i<=n+m;i++)
c[i][t]=1;
for(int i=1;i<=k;i++)
{
scanf("%d%d%d",&a,&x,&y);
if(x*y!=0)
c[x][n+y]=1;
}
printf("%d\n",maxflow(s,t));
}
return 0;
}