【题解】codeforces778C Peterson Polyglot
来源:互联网 发布:多线程socket编程java 编辑:程序博客网 时间:2024/06/01 17:12
题目链接
题意:给定一棵trie树,可以删除一层边,再将父边被删且父亲相同的结点对应的子树合并得到一棵新trie树,求新trie树的最小结点数。
分析:启发式合并。在合并结点u的子树时,选择将小子树合并到大子树里,这样总的合并的时间复杂度是O(nlgn)的。
证明:合并的耗时来自于对小子树的遍历。设全体小子树的遍历总量为T,考虑每个结点u对T的贡献。设结点u可以作为小子树的第i1层、i2层、...、it层(i1<i2<...<it),则结点u对T的贡献为t。由合并的方式(小子树合并到大子树)知对应的子树tree1,tree2,...,treet有size(tree1)<size(tree2)/2<...<size(treet)/2^t。所以t不超过lgn。所以T为nlgn级别的量。
程序实现上可以先正着将结点u的小子树合并到u的最大子树里,再倒着删除,然后考虑u的子结点。
代码
#include<bits/stdc++.h>using namespace std;const int maxn=6e5+10,maxl=26;int n,G[maxn][maxl],sc[maxn],sz[maxn],po[maxn];int f[maxn];void dfs1(int u){sz[u]=1;for (int i=0;i<maxl;i++) if (G[u][i]){ dfs1(G[u][i]); if (sz[G[u][i]]>sz[po[u]]) po[u]=G[u][i];sz[u]+=sz[G[u][i]];}}void Union(int u,int v,int &s){s++;for (int i=0;i<maxl;i++) if (G[u][i]&&G[v][i]) Union(G[u][i],G[v][i],s); else if (G[u][i]&&!G[v][i]) G[v][i]=G[u][i];}void Delete(int u,int v){for (int i=0;i<maxl;i++) if (G[u][i]==G[v][i]) G[v][i]=0; else if (G[u][i]&&G[v][i]) Delete(G[u][i],G[v][i]);}void dfs2(int u,int h){if (!sc[u]) return ;int sum=1;for (int i=0;i<maxl;i++) if (G[u][i]&&G[u][i]!=po[u]) Union(G[u][i],po[u],sum);f[h]+=sum;for (int i=maxl-1;i>=0;i--) if (G[u][i]&&G[u][i]!=po[u]) Delete(G[u][i],po[u]);for (int i=0;i<maxl;i++) if (G[u][i]) dfs2(G[u][i],h+1);}int idx(char c){return c-'a';}int main(){cin>>n;for (int i=1;i<n;i++){int u,v;char ch[2];scanf("%d%d%s",&u,&v,ch);G[u][idx(ch[0])]=v;sc[u]++;}dfs1(1);dfs2(1,1);int ans=1;for (int i=2;i<=n;i++) if (f[ans]<f[i]) ans=i;cout<<n-f[ans]<<endl<<ans;return 0;}
0 0
- 【题解】codeforces778C Peterson Polyglot
- 启发式合并(Peterson Polyglot ,cf 778C)
- Codeforces Round #402 (Div. 1) C. Peterson Polyglot(字典树合并/可持久化字典树)
- polyglot库介绍
- Peterson 算法
- Peterson算法
- Peterson算法
- Peterson算法
- Peterson算法
- Vim插件之vim-polyglot
- Peterson算法(线程间互斥)
- 多线程编程Peterson算法
- Peterson和多线程版本
- Peterson算法感悟
- Redisql: the lightning fast data polyglot【翻译】
- pip install polyglot 出现的问题总结
- peterson互斥算法 1981
- 进程同步03--Peterson算法
- 原生js实现二级联动下拉列表菜单
- Leetcode——486. Predict the Winner
- MatConvnet 初步学习(CPU&GPU)
- JAVA面向对象 Part01 零碎知识点总结
- Qtudp组播编程
- 【题解】codeforces778C Peterson Polyglot
- 八大排序算法 java
- 热修复比较
- GraphX pregel接口
- Vegetable and Road [并查集]
- HDOJ题目分类
- opencv,图像处理,rgb转换为hsv空间
- 浅谈C/C++中运算符的优先级、运算符的结合性以及操作数的求值顺序
- 2017年3月4号。