CF-778 C.Peterson Polyglot (Trie合并)
生活随笔
收集整理的這篇文章主要介紹了
CF-778 C.Peterson Polyglot (Trie合并)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
CF-778 C.Peterson Polyglot(Trie合并)
題目鏈接
題意
給一個TrieTrieTrie樹,問刪除那一層剩下的節點數最少,輸出最小數量的節點數和刪除的最小層數
刪除節點之后,子節點相同的點會合并在一起
思路
枚舉刪除每個節點,計算它對這一層的貢獻
刪除的實現是通過合并節點來實現的
首先新建節點nownownow表示合并之后的節點,此時需要刪除節點xxx即merge(now,x)merge(now,x)merge(now,x)
mergemergemerge的流程是:新建tmptmptmp節點表示合并之后的節點并返回給nownownow,然后從’aaa’ - 'zzz'合并nownownow和xxx,如果nownownow和xxx同時有邊,表示子節點可以合并在一起,所以遞歸下去
最后判斷最小值
#include <bits/stdc++.h> const int maxn = 4e5 + 5; using namespace std; int nex[maxn][26], ans[maxn]; int cnt, n; int merge(int x, int y) {// printf("%d %d\n", x, y);if (x == 0 || y == 0) return x|y;int tmp = ++cnt;for (int i = 0; i < 26; ++i) nex[tmp][i] = merge(nex[x][i], nex[y][i]);return tmp; } void dfs(int u, int level) {int now = n + 1;cnt = now;for (int i = 0; i < 26; ++i) {if (nex[u][i]) now = merge(now, nex[u][i]);}// printf("u %d, level %d, cnt %d\n", u, level, cnt);ans[level] += cnt - n - 1;for (int i = 0; i < 26; ++i) {if (nex[u][i]) dfs(nex[u][i], level+1);} } int main() {scanf("%d", &n);for (int i = 1; i < n; ++i) {int u, v;char c;scanf("%d %d %c", &u, &v, &c);nex[u][c - 'a'] = v;}dfs(1, 1);int sz = 0, p;for (int i = 1; i <= n; ++i) {if (sz < ans[i]) {sz = ans[i];p = i;}}printf("%d\n%d\n", n-sz, p);return 0; }總結
以上是生活随笔為你收集整理的CF-778 C.Peterson Polyglot (Trie合并)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CF-85E.Guard Towers(
- 下一篇: CF-1207 G.Indie Albu