总结 · 二分图匹配

感觉二分图匹配的内容很杂还很难理解。。。需要总结一下啊。。。。。

1.二分图最大匹配:边数最多的匹配叫做最大匹配。

算法:匈牙利算法O(V*E)

例题:BZOJ 1059 题解在这

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<stack>
 6 #include<queue>
 7 #include<cstring>
 8 #define PAU putchar(' ')
 9 #define ENT putchar('\n')
10 #define MSE(a,b) memset(a,b,sizeof(a))
11 #define REN(x) for(ted*e=fch[x];e;e=e->nxt)
12 #define REP(i,s,t) for(int i=s,__=t;i<=__;i++)
13 #define DWN(i,s,t) for(int i=s,__=t;i>=__;i--)
14 using namespace std;
15 const int maxn=200+10,maxm=40000+10;
16 int lnk[maxn];bool vis[maxn];
17 struct ted{int x,y;ted*nxt;}adj[maxm],*fch[maxn],*ms=adj;
18 void add(int x,int y){*ms=(ted){x,y,fch[x]};fch[x]=ms++;return;}int n;
19 bool match(int x){
20     REN(x){int v=e->y;if(!vis[v]){vis[v]=true;
21             if(!lnk[v]||match(lnk[v])){lnk[v]=x;return true;}
22         }
23     }return false;
24 }
25 bool hungary(){
26     MSE(lnk,false);REP(i,1,n){MSE(vis,false);if(!match(i))return false;}return true;
27 }
28 inline int read(){
29     int x=0;bool sig=true;char ch=getchar();
30     for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=false;
31     for(;isdigit(ch);ch=getchar())x=10*x+ch-'0';return sig?x:-x;
32 }
33 inline void write(int x){
34     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
35     int len=0;static int buf[20];while(x)buf[len++]=x%10,x/=10;
36     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
37 }
38 int T;
39 int main(){
40     T=read();while(T--){
41         MSE(fch,NULL);ms=adj;
42         n=read();
43         REP(i,1,n)REP(j,1,n)if(read())add(i,j);
44         puts(hungary()?"Yes":"No");
45     }
46     return 0;
47 }
匈牙利算法

2.二分图最小点覆盖:一个最小的点集V使得所有的边总有一个端点属于V,比如菊花图的最小点覆盖数是1

算法:最小点覆盖=最大匹配

例题:HDU 1150 题解在这

3.二分图最大独立集:一个最大的点集V使得每两点间都不存在边,比如菊花图的最大独立集是n-1。

算法:最大独立集=n-最大匹配

 

你可能感兴趣的:(总结 · 二分图匹配)