BOJ 1707分チャート
11947 ワード
質問する
導入する
図論では、二分図とは、すべての頂点を赤と青に塗りますが、すべてのエッジを赤と青の頂点に塗ります.
問題を答えようと思ったが、結局問題の話しか聞いていなかったので、よく理解できなかったので探してみた.
それはより性質に近いようで、以下のように定義されている.
定義#テイギ#
説明:
考えは簡単だ.
頂点を2つのグループに分ける場合、グループ内には幹線がありません.その名の通り、二部図です.
例えば、赤/緑の点の間には接続されていません.
定義によれば、可能なパケット化方法がある場合は、二分図である.
適用
では、どのようにしてプログラムを通じて実現するのでしょうか.
BFS、DFSなどを検索し、出会った人ごとに隣接する頂点とは反対の色を塗ります.
探索中に色を塗ったやつに出会ったら、塗る色とは逆?それは正義に対する矛盾だ.
したがって、このグラフは二分図ではありません.
このような判別方法で体現すればよい.
コード#コード#
// 2021.12.29 22:50:44
// 1707 https://boj.kr/1707
#include <bits/stdc++.h>
using namespace std;
#define RED 1
#define GREEN 2
#define VERTEX_MAX 20'001
#define EDGE_MAX 200'001
vector<vector<int>> edges(EDGE_MAX, vector<int>());
int visited[VERTEX_MAX];
int invertColor(int color)
{
return color == RED ? GREEN : RED;
}
bool dfs(int vertex, int color)
{
visited[vertex] = color;
for (int next : edges[vertex])
{
if (visited[next] == color)
return false;
if (!visited[next] && !dfs(next, invertColor(color)))
return false;
}
return true;
}
void init()
{
for (int i = 1; i < EDGE_MAX; i++)
edges[i].clear();
for (int i = 1; i < VERTEX_MAX; i++)
visited[i] = 0;
}
int main()
{
cin.tie(0);
ios::sync_with_stdio(false);
int k;
cin >> k;
while (k--)
{
int v, e;
cin >> v >> e;
init();
for (int i = 0; i < e; i++)
{
int v1, v2;
cin >> v1 >> v2;
edges[v1].push_back(v2);
edges[v2].push_back(v1);
}
bool ret = true;
for (int i = 1; i <= v; i++)
{
if (!visited[i] && !(ret = dfs(i, RED)))
break;
}
cout << (ret ? "YES" : "NO") << '\n';
}
}
初期化の問題でシャベルをよく使います.初期化に気をつけて...
リファレンス
Wikipedia
Reference
この問題について(BOJ 1707分チャート), 我々は、より多くの情報をここで見つけました https://velog.io/@0chil/BOJ-1707-이분-그래프テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol