每个工作用一条边代表,用最小的点覆盖所有的边,也就是找出最小覆盖。 公式:最小覆盖=最大匹配;对原二分图做一次最大匹配 #include<iostream> using namespace std; const int MAX=1005; int map[MAX][MAX]; int match[MAX]; bool vis[MAX]; int n,m; bool can(int t) { for(int i=1;i<=m;i++) { if(map[t][i]&&vis[i]==0) { vis[i]=1; if(match[i]==-1 || can(match[i])) { match[i]=t; return true; } } } return false; } int main() { freopen("in.txt","r",stdin); int nn,mm,kk; cin>>nn; while(nn!=0) { cin>>mm>>kk; n=nn; m=mm; memset(map,0,sizeof(map)); for(int i=1;i<=kk;i++) { int x,a,b; cin>>x>>a>>b; if(a*b!=0) map[a][b]=1; } memset(match,-1,sizeof(match)); int ans=0; for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if(can(i)) ans++; } cout<<ans<<endl; cin>>nn; } return 0; }