感觉二分图匹配的内容很杂还很难理解。。。需要总结一下啊。。。。。
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-最大匹配