今天复习二分匹配,A 了一道模板题。
二分匹配需要理解增广路的寻找。用dfs来更新最大匹配。注意一些点:赋初值;愚蠢地把==写成了= ; 然后match的记值;每个点都要重新走一遍。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define INF 80005 6 #define maxn 405 7 using namespace std; 8 int n,m,ans,match[maxn]; 9 int tot,he[maxn],to[INF],ne[INF]; 10 bool check[maxn]; 11 void add(int a,int b) 12 { 13 tot++;to[tot]=b;ne[tot]=he[a];he[a]=tot; 14 } 15 bool findway(int x) 16 { 17 for (int i=he[x];i;i=ne[i])//dfs 18 if (!check[to[i]]){ 19 check[to[i]]=true; 20 if (match[to[i]]==-1||findway(match[to[i]])){ //not findway(to[i]) 21 match[to[i]]=x;//<qwq> == not = 22 return true; 23 } 24 } 25 return false; 26 } 27 int KM ()//hungray 28 { 29 ans=0; 30 memset(match,-1,sizeof (match)); 31 for (int i=1;i<=n;i++) //if (match[i]=-1) 32 { 33 memset(check,0,sizeof (check)); 34 if (findway(i)) ans++; 35 } 36 return ans; 37 } 38 int main() 39 { 40 freopen("poj1274.in","r",stdin); 41 while (cin>>n>>m){ 42 memset(ne,0,sizeof(ne)); 43 memset(to,0,sizeof (to)); 44 memset(he,0,sizeof (he)); 45 tot=0;//赋初值 46 for (int i=1;i<=n;i++) 47 { 48 int a;scanf("%d",&a); 49 for (int j=1;j<=a;j++) 50 { 51 int b;scanf("%d",&b); 52 b+=n;//!!! 53 add(i,b);add(b,i); 54 } 55 } 56 printf("%d ",KM()); 57 } 58 return 0; 59 }