CodeForces - 965E Short Code (字典树上贪心)
生活随笔
收集整理的這篇文章主要介紹了
CodeForces - 965E Short Code (字典树上贪心)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出n個互不相同的字符串,現在要求n個互不相同的前綴,問所有前綴的長度和最短是多少
題目分析:因為涉及到了前綴,所以我們可以用字典樹來解決,又因為需要長度和最短,所以我們可以貪心來做,具體實現還是需要借助stl里的優先隊列或者set容器,時間復雜度都是nlogn,這里我是用優先隊列做的,在建立字典樹的時候,對于結尾的字母,我們需要標記一下,最后我們可以得到一棵每個節點非0即1的字典樹(因為題目保證了兩兩字符串互不相同,所以肯定不可能有互相干擾的節點),然后這棵樹中肯定有n個1,所以我們盡可能的讓這n個1的深度在樹上變小即可,我們可以在每個節點都維護一個優先隊列,然后根據樹的遍歷,利用dfs深搜,最初到達字典樹的最深一層,也就是葉子節點開始搜索:
如此往復的回溯,到最后我們字典樹的根節點的優先隊列,肯定是有n個元素的,也就是本題的答案了,記錄一下就好了
代碼:
#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> #include<unordered_map> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e5+100;priority_queue<int>q[N];char s[N];int cnt=0;int trie[N][26];bool vis[N];void insert() {int pos=0;for(int i=0;s[i];i++){int to=s[i]-'a';if(!trie[pos][to])trie[pos][to]=++cnt;pos=trie[pos][to];}vis[pos]=true; }void merge(int a,int b) {while(q[b].size()){q[a].push(q[b].top());q[b].pop(); } }void dfs(int pos,int deep) {for(int i=0;i<26;i++)if(trie[pos][i]){dfs(trie[pos][i],deep+1);merge(pos,trie[pos][i]);}if(!deep)return;if(vis[pos]){q[pos].push(deep);}else{if(q[pos].top()>deep){q[pos].pop();q[pos].push(deep);}} }int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%s",s);insert();}dfs(0,0);int ans=0;while(q[0].size()){ans+=q[0].top();q[0].pop();}printf("%d\n",ans);return 0; }?
總結
以上是生活随笔為你收集整理的CodeForces - 965E Short Code (字典树上贪心)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CodeForces - 566A Ma
- 下一篇: HDU - 6153 A Secret(