二分图匹配可用匈牙利算法,离散中学过,就是找一条交替链,让路径的起点和终点都是还没有匹配过的点,路径经过的连线是一条没被匹配、一条已经匹配过,再下一条又没匹配这样交替地出现,显然路径里没被匹配的连线比已经匹配了的连线多一条,于是修改匹配图,把路径里所有匹配过的连线去掉匹配关系,把没有匹配的连线变成匹配的,这样匹配数就比原来多1个。不断执行上述操作,直到找不到这样的路径为止。
POJ-1274-The Perfect Stall
http://poj.org/problem?id=1274
基本的二分图匹配,套模版即可
#include<stdio.h> #include<string.h> #include<stdlib.h> int n,m; int map[205][205]; int state[205]; //记录每个点是否被搜索过 int result[205]; //记录匹配点的编号 int find(int a) { int i; for(i=1;i<=m;i++) if(!state[i]&&map[a][i]) //如果节点i与a相邻并且未被查找过 { state[i]=1; //标记i为已查找过 if(result[i]==0||find(result[i])) //如果i未在前一个匹配M中 || i在匹配M中,但是从与i相邻的节点出发可以有增广路 { result[i]=a; //记录查找成功记录 return 1; } } return 0; } int main() { int i,t,temp,ans; while(scanf("%d%d",&n,&m)!=EOF) { memset(map,0,sizeof(map)); for(i=1;i<=n;i++) //建图 { scanf("%d",&t); while(t--) { scanf("%d",&temp); map[i][temp]=1; } } ans=0; memset(result,0,sizeof(result)); for(i=1;i<=n;i++) { memset(state,0,sizeof(state)); //清空上次搜索时的标记 if(find(i)) //从节点i尝试扩展 ans++; } printf("%d\n",ans); } return 0; }