agc032_c

Posted skiceanakacniu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了agc032_c相关的知识,希望对你有一定的参考价值。

agc032_c

题解

每个节点的度数必然是偶数。因为每个环中的结点是偶数,所以合起来也是偶数。

利用这再结合边数至少为点数 (+2) 就可以骗到挺多的分数哦。

考虑看每个结点的度数看回路的数量。

如果存在一个节点的度数 (ge 6) ,那么这个图的回路必然经过这个结点三次。所以必然可以拆成三个环。

那么剩下就是节点度数为(2) 或者(4) 。如果所有节点度数均为 (2) ,那么这张图是一个环。显然不行。剩下情况考虑将所有度数为 (2) 的点都「缩掉」,也就是把读书为 (2) 的点看成一条边。那么剩下的就只有度数为 (4) 的点了。那么分为三种情况讨论:

  1. 度数为 (4) 的点至少有3个。有解。
  2. 度数为 (4) 的点只有 (2) 个。
  3. 度数为 (4) 的点只有一个。无解。

其中第二种情况还需要细分一下,如果这两个结点之间有四条边,必然不行。否则必然是两个节点之间有两条边,各自有一个自环,这是可以的。

总结

  • 可以考虑根据结点度数研究换的问题。

代码

用一个Dfs随便判断一下是那种情况就行(度数为 (2) 的哪种情况)

很明显和小粉兔写的非常像,这是因为我参照了他的题解。。。

#include <cstdio>
#include <vector>
using namespace std;
const int NM = 1e5 + 5;
int n, m, deg[NM], c4, stk[NM], tp, cnt;
vector<int> G[NM];
bool vis[NM];
void DFS(int u) {
	vis[u] = 1, ++cnt;
	for (int v : G[u]) if (!vis[v]) DFS(v);
}
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= m; ++i) {
		int u, v;
		scanf("%d%d", &u, &v);
		G[u].push_back(v);
		G[v].push_back(u);
		++deg[u];
		++deg[v];
	}
	for (int i = 1; i <= n; ++i) {
		if (deg[i] & 1) {
			printf("No
");
			return 0;
		}
		if (deg[i] == 4)
			stk[++c4] = i;
	}
	for (int i = 1; i <= n; ++i) {
		if (deg[i] >= 6) {
			printf("Yes
");
			return 0;
		}
	}
	if (c4 >= 3) {
		printf("Yes
");
		return 0;
	} else if (c4 == 2) {
		vis[stk[2]] = 1;
		DFS(stk[1]);
		if (cnt == n - 1)
			printf("No
");
		else printf("Yes
");
	} else
		printf("No
");
	return 0;
}

以上是关于agc032_c的主要内容,如果未能解决你的问题,请参考以下文章

AtCoder AGC032D Rotation Sort (DP)

AtCoder AGC032F One Third (组合计数DP概率期望微积分)

agc045_c Range Set

C++_引用做函数的返回值_引用的本质---C++语言工作笔记032

「题解」agc031_c Differ by 1 Bit

pfsense中文版下载(包括。2.032.252.322.332.34等)