[题目链接](F - Add One Edge 2 (atcoder.jp))
Problem Statement
You are given a tree with N N N vertices. The i i i-th edge ( 1 ≤ i ≤ N − 1 ) (1 \leq i \leq N-1) (1≤i≤N−1) connects vertices u i u_i ui and v i v_i vi bidirectionally.
Adding one undirected edge to the given tree always yields a graph with exactly one cycle.
Among such graphs, how many satisfy all of the following conditions?
- The graph is simple.
- All vertices in the cycle have degree 3 3 3.
中文题意
问题陈述
给你一棵有 N N N 个顶点的树。 i − t h i -th i−th 边 ( 1 ≤ i ≤ N − 1 ) (1 \leq i \leq N-1) (1≤i≤N−1) 双向连接顶点 u i u_i ui 和 v i v_i vi 。
在给定的树上添加一条无向边会得到一个有一个循环的图。
在这些图中,有多少个满足以下所有条件?
- 图很简单。
- 循环中的所有顶点都有度数 3 3 3 。
Constraints
- 3 ≤ N ≤ 2 × 1 0 5 3 \leq N \leq 2 \times 10^5 3≤N≤2×105
- 1 ≤ u i , v i ≤ N 1 \leq u_i, v_i \leq N 1≤ui,vi≤N
- The given graph is a tree.
- All input values are integers.
Input
The input is given from Standard Input in the following format:
N N N
u 1 u_1 u1 v 1 v_1 v1
u 2 u_2 u2 v 2 v_2 v2
⋮ \vdots ⋮
u N − 1 u_{N-1} uN−1 v N − 1 v_{N-1} vN−1
Output
Print the answer.
Sample Input 1
6
1 2
2 3
3 4
4 5
3 6
Sample Output 1
1
Adding an edge connecting vertices 2 2 2 and 4 4 4 yields a simple graph where all vertices in the cycle have degree 3 3 3, so it satisfies the conditions.
Sample Input 2
7
1 2
2 7
3 5
7 3
6 2
4 7
Sample Output 2
0
There are cases where no graphs satisfy the conditions.
Sample Input 3
15
1 15
11 14
2 10
1 7
9 8
6 9
4 12
14 5
4 9
8 11
7 4
1 13
3 6
11 10
Sample Output 3
6
解法
考虑,新增加一条边必然会使得所连接的两个点的度数 + 1 + 1 +1。现在要求环上的所有节点的度数都为 3 3 3 ,在这里我们可以对目前树中部分度数为3的点视为一个连通块。然后我们对于每一个顶点,依次统计一下与其相连的节点度数是否为 2 2 2。如果是 2 2 2,将 cnt
的数量 + 1 +1 +1 ,因为每次连接成环的话,是选择其中两个顶点,那么最后的答案数为 C n 2 C_{n}^{2} Cn2 。
typedef long long LL;
std::vector<int> G[N];
int deg[N];
bool visit[N];
LL cnt, ans;void dfs(int v, int fa = 0) {if(deg[v] != 3) {// v是一个周边的点cnt += (deg[v] == 2);return ;}visit[v] = 1;for (auto x : G[v]) {if(x == fa) continue;dfs(x, v);}
}void solved() {/* your code */int n;cin >> n;for (int i = 1; i < n; i ++) {int u, v;cin >> u >> v;G[u].push_back(v); G[v].push_back(u);deg[u] ++, deg[v] ++;}for (int i = 1; i <= n; i ++) {//找度数为3的连通块if(deg[i] != 3) continue; if(visit[i]) continue;cnt = 0;dfs(i);ans += 1LL * cnt * (cnt - 1) / 2; }cout << ans << endl;
}
总结
本道题目,看似是一个树的题目。我们将其转化为了一个dfs
型的联通块计算题目。然后使用组合计数即可。