[Atcoder AGC032C]Three Circuits

題目大意:有一張$n$個點$m$條邊的無向連通圖,判斷是否能夠從中分出$3$個環,知足三個環覆蓋整張圖而且沒有重複的邊。$n,m\leqslant10^5$ios

題解:分類討論。有度數爲奇確定不行,由於連通,因此若環數目大於$3$必定能夠合併,因此只須要排除環數目小於$3$的狀況。spa

當全部點度數小於$4$時確定不行,當最大的度數大於$4$時必定能夠。接下來就討論最大點度數爲$4$的狀況。當只有一個點度數爲$4$時,至關於兩個自環,不能夠。當有大於兩個點度數爲$4$時能夠。有兩個點度數爲$4$時,除了下面這種狀況其他都可。blog

而這種狀況的判斷只須要看點$A$是否能夠不經過點$B$回到自身,是就能夠,不然就是上面這種狀況。ci

卡點:it

 

C++ Code:io

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
const int maxn = 1e5 + 10;

int n, m, deg[maxn], Max, Cnt, A, B;

int head[maxn], cnt;
struct Edge { int to, nxt; } e[maxn << 1];
void addedge(int a, int b) {
	e[++cnt] = (Edge) { b, head[a] }; head[a] = cnt;
	e[++cnt] = (Edge) { a, head[b] }; head[b] = cnt;
	++deg[a], ++deg[b];
}

void dfs(int u, int fa = 0) {
	if (u == A && fa) std::cout << "Yes\n", exit(0);
	if (u == B) return ;
	for (int i = head[u], v; i; i = e[i].nxt)
		if ((v = e[i].to) != fa) dfs(v, u);
}
int main() {
	std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
	std::cin >> n >> m;
	for (int i = 0, a, b; i < m; ++i) std::cin >> a >> b, addedge(a, b);
	for (int i = 1; i <= n; ++i) if (deg[i] & 1) {
		std::cout << "No\n";
		return 0;
	} else {
		Max = std::max(Max, deg[i]);
		if (deg[i] == 4) { ++Cnt; if (A) B = i; else A = i; }
	}
	if (Max < 4 || (Max == 4 && Cnt == 1)) { std::cout << "No\n"; return 0; }
	if (Max > 4 || Cnt > 2) { std::cout << "Yes\n"; return 0; }
	dfs(A), std::cout << "No\n";
	return 0;
}
相關文章
相關標籤/搜索