33.图的增边

描述

思路

这里首先要明确二分图是一种什么类型的图,二分图的定义是图中所有的节点被分为两个部分,两部分之间的节点可以存在边,但是两个部分的内部不能存在连边。
这里可以看成是一个染色的问题,把图中所有的节点进行广度优先遍历,每一层的节点染成不同的颜色,然后统计两种颜色的节点的个数,最后两者相乘,减去现有的边的个数,即为最后的答案。

代码

#include <bits/stdc++.h>
#include <vector>
using namespace std;

/* 二分图的定义
图的所有节点被分为两个部分,每个部分中的某些可能是相连的,但是相同部分的顶点之间不连接
*/

// 先进行染色操作
void track_color(int cur, int color,vector<int>& edges,vector<vector<int>>& graph){
    if(edges[cur] != -1) return;
    edges[cur] = color;
    // 做异或操作,color的值在0和1之间不停的变化
    color ^= 1;
    for(auto next : graph[cur]){
        track_color(next, color, edges, graph);
    }
}

int main(){
    int n,m,u,v;
    cin >> n >>m ;
    // 记录是否已经被染色了
    vector<int> edges(n+1,-1);
    vector<vector<int>> graph(n+1,vector<int>());

    for(int i = 1;i<=n;i++){
        cin >> u >> v;
        graph[u].push_back(v);
        graph[v].push_back(u);
    }

    long long count = 0;
    track_color(1, 1, edges, graph);

    // 记录染色集合中两个集合的节点的个数
    for(int i = 1;i<=n;i++){
        if(edges[i] == 1){
            count++;
        }
    }

    // 还能再添加的边的个数即为两个集合中节点个数的乘积减去现有的边的个数。
    count *= n-count;

    cout << count - m << endl;

    return 0;
}

posted @ 2024-10-01 18:25  alone_qing  阅读(6)  评论(0)    收藏  举报