D - Make Bipartite 2
D - Make Bipartite 2
https://atcoder.jp/contests/abc282/tasks/abc282_d
Simple Graph
https://mathworld.wolfram.com/SimpleGraph.html
A simple graph, also called a strict graph (Tutte 1998, p. 2), is an unweighted, undirected graph containing no graph loops or multiple edges (Gibbons 1985, p. 2; West 2000, p. 2; Bronshtein and Semendyayev 2004, p. 346). A simple graph may be either connected or disconnected.
Unless stated otherwise, the unqualified term "graph" usually refers to a simple graph. A simple graph with multiple edges is sometimes called a multigraph (Skiena 1990, p. 89).
Multigraph
https://mathworld.wolfram.com/Multigraph.html
The term multigraph refers to a graph in which multiple edges between nodes are either permitted (Harary 1994, p. 10; Gross and Yellen 1999, p. 4) or required (Skiena 1990, p. 89, Pemmaraju and Skiena 2003, p. 198; Zwillinger 2003, p. 220). West (2000, p. xiv) recommends avoiding the term altogether on the grounds of this ambiguity.
Bipartite Graph -- 二分图
https://mathworld.wolfram.com/BipartiteGraph.html
A bipartite graph, also called a bigraph, is a set of graph vertices decomposed into two disjoint sets such that no two graph vertices within the same set are adjacent. A bipartite graph is a special case of a k-partite graph with . The illustration above shows some bipartite graphs, with vertices in each graph colored based on to which of the two disjoint sets they belong.
Bipartite graphs are equivalent to two-colorable graphs. All acyclic graphs are bipartite. A cyclic graph is bipartite iff all its cycles are of even length (Skiena 1990, p. 213).
二分图判断
code
https://www.geeksforgeeks.org/bipartite-graph/
https://www.zhihu.com/question/292465499
如何判定
相信大家一定对二分图有了一个初步的了解,那么我们该如何判定二分图呢?
首先我们要引进一个概念,染色
判断二分图的常见方法是染色法:用两种颜色,对所有顶点逐个染色,且相邻顶点染不同的颜色
如果发现相邻顶点染了同一种颜色,就认为此图不为二分图
当所有顶点都被染色,且没有发现同色的相邻顶点,就退出
参考
https://atcoder.jp/contests/abc282/submissions/37362401
需要处理存在多个孤立图的情况。
对于每个独立图, 分别计算 同色的点的数量,
独立图之间任意连线是有效的。
#include <bits/stdc++.h> using namespace std; #include <atcoder/all> using namespace atcoder; #define rep(i,a,b) for(int i=a;i<b;i++) #define rrep(i,a,b) for(int i=a;i>=b;i--) #define fore(i,a) for(auto &i:a) using ll = long long; using P = pair<int,int>; using Graph = vector<vector<int>>; using mint = modint1000000007; map<ll,vector<ll>> uv; vector<ll> node; vector<ll> black; vector<ll> white; bool color(int current, int col){ node[current] = col; if(col == 1){ black.push_back(current); } else{ white.push_back(current); } ll rev; if(col == 1){ rev = -1; } else{ rev = 1; } for(ll nod: uv[current]){ if(node[nod] == col){ return false; } else if(node[nod] == 0){ if (!color(nod, rev)){ return false; } } } return true; } int main() { ll n,m; cin >> n >> m; node.assign(n+1,0); rep(i,0,m){ int u,v; cin >> u >> v; uv[u].push_back(v); uv[v].push_back(u); } ll sameColors = 0; rep(i,1,n+1){ if(node[i] == 0){ black.clear(); white.clear(); if(!color(i,1)){ cout << "0" << endl; return 0; } ll bSize = (int)black.size(); ll wSize = (int)white.size(); sameColors += bSize*(bSize-1)/2 + wSize*(wSize-1)/2; } } //同じ色 cout << n*(n-1)/2-m-sameColors << endl; return 0; }