二分图的判断与匹配

二分图:一定没有奇数环,可能包含长度为偶数的环, 而且不一定是连通图

染色法判定二分图:

采用前向星 + 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;
}

猜你喜欢

转载自blog.csdn.net/messywind/article/details/113631095
今日推荐