二分圖的判斷與匹配
阿新 • • 發佈:2021-02-05
二分圖:一定沒有奇數環,可能包含長度為偶數的環, 而且不一定是連通圖
染色法判定二分圖:
採用前向星
+
d
f
s
+dfs
+dfs的方法。開個
c
o
l
o
r
color
color陣列代表染的顏色(
0
0
0表示未被染色,
1
1
1和
2
2
2代表兩個顏色)。依次從每個點開始搜尋,如果該點未被染色,就開始
d
f
s
dfs
dfs搜尋,如果返回
0
0
0就說明染色失敗,不是二分圖,標記失敗,跳出循壞。
搜尋部分:依次訪問鄰接表可達的每個節點,如果沒有被染色過,就試圖用第二個顏色來染下一個節點,如果被染色過且顏色相同,則染色失敗,返回
0
0
0。
程式碼:
#include< bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m,u,v,h[N],e[N],ne[N],idx,color[N];
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
bool dfs(int x,int c){
color[x]=c;
for(int i=h[x];i!=-1;i=ne[i]){
int j=e[i];
if(!color[j]){
if(!dfs(j, 3-c)) return 0;
}
else if(color[j]==c) return 0;
}
return 1;
}
int main(){
memset(h,-1,sizeof h);
cin>>n>>m;
while(m--){
cin>>u>>v;
add(u,v),add(v,u);
}
bool flag=1; //標記
for(int i=1;i<=n;i++){
if(!color[i] ){
if(!dfs(i,1)){
flag=0;
break;
}
}
}
if(flag) puts("Yes");
else puts("No");
}
二分圖的最大匹配:
二分圖的匹配:給定一個二分圖 G G G,在 G G G的一個子圖 M M M中, M M M的邊集 E {E} E中的任意兩條邊都不依附於同一個頂點,則稱 M M M是一個匹配。
二分圖的最大匹配:所有匹配中包含邊數最多的一組匹配被稱為二分圖的最大匹配,其邊數即為最大匹配數。
求最大匹配數:
m
a
t
c
h
match
match陣列表示已有的配對。首先遍歷每個點,尋找這個點連通的另一個點,如果另一個點沒有被匹配,那麼就成功預訂配對,如果連通的另一個點有被匹配但是他的匹配節點擁有另一個可選擇匹配的點,那麼就讓另一個可選擇匹配的點去匹配原來的點。
(有點繞)
程式碼:
#include<bits/stdc++.h>
using namespace std;
const int N=505,M=1e5+5;
int n1,n2,m,u,v,ne[M],e[M],h[N],idx,match[N],res;
bool st[N];
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int find(int x){
for(int i=h[x];i!=-1;i=ne[i]){
int j=e[i];
if(!st[j]){
st[j]=1;
if(!match[j]||find(match[j])){
match[j]=x;
return 1;
}
}
}
return 0;
}
int main(){
memset(h,-1,sizeof h);
cin>>n1>>n2>>m;
while(m--){
cin>>u>>v;
add(u,v);
}
for(int i=1;i<=n1;i++){
memset(st,0,sizeof st);
if(find(i)) res++;
}
cout<<res<<endl;
}