二分圖學習與總結筆記
阿新 • • 發佈:2019-05-02
sca 匈牙利 算法 連續 總結 bubuko clu head con
二分圖也就是給定關系,劃分成兩個集合,使得各自集合的元素沒有關系連接!
在這裏不深刻探討如何實現,而是通過算法來進行學習,二分圖是一類非常簡單的問題
但是最重要的還是圖論中匹配模型的構造,要註意二分圖的構造還不是非常容易的
匈牙利算法
1 bool match(int x){ 2 for(int i=head[x];i;i=next[i]){ 3 int y=ver[i]; 4 if(!vis[y]){ 5 vis[y]=true; 6 if(!matched[y] || match(matched[y])){7 matched[y]=x; 8 return true; 9 } 10 } 11 } 12 return false; 13 }
註意每次進行match的時候需要將vis進行MEMSET
match->true匹配成功否則匹配失敗
P1197 SCOI 2010 連續攻擊遊戲
1 #include <cstdio> 2 #include <cstring> 3 4 const int MAXN=(int)1e6+5,MAXM=(int)4e6+5; 5 int ver[MAXM],next[MAXM],head[MAXN],tot; 6 int matched[MAXN]; 7 bool vis[MAXN]; 8 9 void read(int &num){ 10 char c=getchar(); 11 num=0; 12 while(c<‘0‘ || c>‘9‘) c=getchar(); 13 while(c>=‘0‘ && c<=‘9‘) num=(num*10+c-‘0‘),c=getchar();14 } 15 16 void add(int u,int v){ 17 ver[++tot]=v; 18 next[tot]=head[u]; 19 head[u]=tot; 20 } 21 22 bool match(int x){ 23 for(int i=head[x];i;i=next[i]){ 24 int y=ver[i]; 25 if(!vis[y]){ 26 vis[y]=true; 27 if(!matched[y] || match(matched[y])){ 28 matched[y]=x; 29 return true; 30 } 31 } 32 } 33 return false; 34 } 35 36 int main(){ 37 int n,a,b; 38 scanf("%d",&n); 39 for(int i=1;i<=n;i++){ 40 read(a),read(b); 41 add(a,i),add(b,i); 42 } 43 int ans=0; 44 for(int i=1;i<=10000;i++){ 45 memset(vis,0,sizeof(vis)); 46 if(match(i)) ans++; 47 else break; 48 } 49 printf("%d",ans); 50 return 0; 51 }
二分圖學習與總結筆記