066.二分图判定

二分图

二分图定义

二分图的顶点集可分割为两个互不相交的子集,图中每条边依附的两个顶点都分属于这两个子集,且两个子集内的顶点不相邻。

判定 - 染色法

遍历一遍图,一边遍历一边染色,尝试用两种颜色给所有节点染色,且相邻节点的颜色都不相同

  • 图不一定连通,尝试每一个未访问的起点

  • 只要有一个连通分量无法二分,整个图就无法二分

模板

class Solution {
    bool f=1;
    int n;
    void dfs(vector<vector<int>>&gra,vector<bool>&vis,vector<int>&tag,int u,int cur){
        if(f==0)return;
        vis[u]=1;
        tag[u]=cur;
        for(int v:gra[u]){
            if(vis[v]==0){
                dfs(gra,vis,tag,v,cur^1);
            }
            else{
                if(tag[v]==cur){
                    f=0;
                    return;
                }
            }
        }
    }
public:
    bool isBipartite(vector<vector<int>>& gra) {
        this->n=gra.size();
        vector<bool>vis(n,0);
        vector<int>tag(n,0);
        for(int i=0;f&&i<n;++i){
            if(vis[i]==0){
                dfs(gra,vis,tag,i,0);
            }
        }
        return f;
    }
};

练习建图

class Solution {
    vector<vector<int>>gra;
    vector<bool>vis;
    vector<bool>tag;
    bool f;
    void dfs(int u,int cur){
        if(f==0)return;
        vis[u]=1;
        tag[u]=cur;
        for(int v:gra[u]){
            if(vis[v]==0){
                dfs(v,cur^1);
            }
            else{
                if(tag[v]==tag[u]){
                    f=0;
                    return;
                }
            }
        }
    }
public:
    bool possibleBipartition(int n, vector<vector<int>>& dislikes) {
        gra.resize(n+1);
        vis.resize(n+1,0);
        tag.resize(n+1,0);
        f=1;
        for(auto &e:dislikes){
            gra[e[1]].push_back(e[0]);
            gra[e[0]].push_back(e[1]);
        }
        for(int i=1;f&&i<=n;++i){
            if(vis[i]==0){
                dfs(i,0);
            }
        }
        return f;
    }
};
posted @ 2026-01-29 23:31  射杀百头  阅读(2)  评论(0)    收藏  举报