首页 > 其他分享 >二分图

二分图

时间:2023-04-15 17:33:27浏览次数:31  
标签:二分 vis color graph int 节点

二分图简介

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

image
首先,二分图作为一种特殊的图模型,会被很多高级图算法(比如最大流算法)用到,不过这些高级算法我们不是特别有必要去掌握,有兴趣的读者可以自行搜索。
从简单实用的角度来看,二分图结构在某些场景可以更高效地存储数据。
image
每个电影节点的相邻节点就是参演该电影的所有演员,每个演员的相邻节点就是该演员参演过的所有电影,非常方便直观。类比这个例子,其实生活中不少实体的关系都能自然地形成二分图结构,所以在某些场景下图结构也可以作为存储键值对的数据结构(符号表)。

判定二分图

首先我们介绍双色问题:给定一幅图,请你用两种颜色将图中的所有顶点着色,且使得任意一条边的两个端点的颜色都不相同。
判定二分图的算法很简单,就是用代码解决「双色问题」。说白了就是遍历一遍图,一边遍历一遍染色,看看能不能用两种颜色给所有节点染色,且相邻节点的颜色都不相同。可以采用DFS或者BFS。

例题1

看一道例题:判断二分图
image
image
代码如下:

class Solution {
public:
    vector<int> color;
    vector<int> vis;
    bool flag = true;
    bool isBipartite(vector<vector<int>>& graph) {
        int n = graph.size();
        color.resize(n), vis.resize(n);
        fill(color.begin(), color.begin() + n, 0);
        fill(vis.begin(), vis.begin() + n, 0);
        // 因为图不一定是联通的,可能存在多个子图
        // 所以要把每个节点都作为起点进行一次遍历
        // 如果发现任何一个子图不是二分图,整幅图都不算二分图
        for(int v = 0; v < n; v++)
        {
            if((!vis[v]))
            {
                vis[v] = 1;
                DFS(graph, v);
            }
        }
        return flag;
    }

    void DFS(vector<vector<int>>& graph, int v)
    {
        // 如果已经确定不是二分图了,就不用浪费时间再递归遍历了
        if(!flag) return;

        for(auto& p: graph[v])
        {
            // 相邻节点 p 没有被访问过
            // 那么应该给节点 p 涂上和节点 v 不同的颜色
            if(!vis[p])
            {
                color[p] = (color[v] == 0 ? 1 : 0);
                vis[p] = 1;
                DFS(graph, p);
            }
            else
            {
                // 相邻节点 p 已经被访问过
                // 根据 v 和 p 的颜色判断是否是二分图
                if(color[v] == color[p])
                {
                    flag = false;
                    return;
                }
            }
        }
    }
};

例题2

可能的二分法
image
显然,把人看作图中的节点,把讨厌的关系看作是边,两个互相讨厌的人不能在相邻节点,则意味着图中相邻节点不能在同一组。所以该题目等价为双色问题。
代码如下:

class Solution {
public:
    bool color[2001] = {false};
    bool vis[2001] = {false};
    bool flag = true;
    bool possibleBipartition(int n, vector<vector<int>>& dislikes) 
    {
        //编号从1开始
        //建图
        vector<vector<int>> graph(n + 1, vector<int>());
        for(auto& p : dislikes)
        {
            int v = p[0];
            int w = p[1];
            //无向图相当于双向图
            graph[v].push_back(w);
            graph[w].push_back(v);
        }
        for(int v = 1; v <= n; v++)
        {
            if(!flag) return false;
            
            if(!vis[v])
            {
                vis[v] = true;
                DFS(graph, v);
            }
        }
        return flag;
    }
    void DFS(vector<vector<int>> graph, int v)
    {
        if(!flag) return;
        for(auto& p : graph[v])
        {
            if(!vis[p])
            {
                color[p] = !color[v];
                vis[p] = true;
                DFS(graph, p);
            }
            else
            {
                if(color[p] == color[v])
                {
                    flag = false;
                    return;
                }
            }
        }
    }
};

参考文献

二分图的判定

标签:二分,vis,color,graph,int,节点
From: https://www.cnblogs.com/parallel-138/p/17321496.html

相关文章

  • AGC002D Stamp Rally 多种做法 kruskal重构树/可持久化并查集/整体二分
    D-StampRally(atcoder.jp)这题做法很多,我写的是可持久化并查集做法,但是裸的可持久化并查集是$O(nlog^3n)$,能过但是很慢!看洛谷的题解有一位大佬写了一个很妙的并查集的写法,按秩合并,每一步合并时用vector记录一下这个被合并到的节点的size和当前的时间,这样做可以找到每一个时......
  • 代码随想录算法训练营Day01 | LeetCode704 二分查找、Leetcode27 移除元素
    今日学习的视频和文章代码随想录数组基础复习基础知识代码随想录二分查找代码随想录移除元素LeetCode704二分查找题目链接:704.二分查找-力扣(Leetcode)以前学二分查找的时候,真的一直搞不清楚怎么操作左边界和有边界,以及循环的终止条件是什么,总是自己慢慢调试出来,......
  • 二分法查找子序列
    判断子序列二分思路主要是对t进行预处理,用一个字典index将每个字符出现的索引位置按顺序存储下来intm=s.length(),n=t.length();vector<vector<int>>index(256,vector<int>());//先记下t中每个字符出现的位置for(inti=0;i<n;i++){charc=t[i];......
  • POJ 1905 Expanding Rods (二分+计算几何+精度处理)
    题目地址:POJ1905用二分枚举h,然后判断弧长是否符合条件。重点还是在精度问题上,具体看代码吧。。#include<iostream>#include<string.h>#include<math.h>#include<queue>#include<algorithm>#include<stdlib.h>#include<map>#include<set>#include......
  • 二分基础
    复健\(Day2\)今天复习二分,使用这种方法的比较明显的提示是使最大值最小,最小值最大,并且原序列有序或者说可以忽略次序二分的基本模板https://www.acwing.com/blog/content/2112/题目\(1.Acwing102\)https://www.acwing.com/problem/content/104/向下取整函数\(floor\),\(doub......
  • 二分图学习笔记
    定义>\(1.\)点数量\(\ge\)2>\(2.\)没有奇环二分图染色>深搜,0和1两种,相邻染不一样颜色,如果最后有冲突就不是二分图。二分图匹配>######定义>>没有\(2\)条边公用\(1\)个点>>--->>######极大匹配>>无法通过加边的方式增加匹配的数量>>--->>###......
  • UVa 10049 Self-describing Sequence (自描述序列&二分递推)
    10049-Self-describingSequenceTimelimit:3.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=34&page=show_problem&problem=990SolomonGolomb's self­describingsequence  istheonlynon­decreas......
  • UVa 10004 Bicoloring (DFS&二分图)
    10004-BicoloringTimelimit:3.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=945In1976the``FourColorMapTheorem"wasprovenwiththeassistanceofacomput......
  • 二分查找 (easy 704. 二分查找)
    虽然也刷了一些题了,但是没有总结,这样效率不高.之后刷题都写一下总结.LeetCode上的标记:红色不通过紫色有待优化绿色达到期望(easy704.二分查找)......
  • 利用envi计算二分类(多分类)精度评价指标及混淆矩阵计算
    前言  导师需要我将预测的几个结果单独计算出每一张图的精度评价,包含以下指标:iou,recall,F1。  因为他说我利用代码批量计算的结果有误。  如果是这样的话可就坏了,希望我的结果没有出太多错误,不然已经做过计算的某些内容又需要全部重新计算了。利用envi计算精度指标使用t......