4567: [Scoi2016]背单词
2017-07-31 10:41
330 查看
逆序插入字典树,dfs时每次先搜单词数最少的子树。
然而这是错的。
反例输入:
7
aa
aba
abb
ba
bb
bc
bd
然后你就挂了。
因此必须缩点,dfs时每次找size最小的子树。
代码:
然而这是错的。
反例输入:
7
aa
aba
abb
ba
bb
bc
bd
然后你就挂了。
因此必须缩点,dfs时每次找size最小的子树。
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<vector> #include<algorithm> #include<map> #include<cmath> #include<queue> using namespace std; #define rep(i,j,k) for(i=j;i<=k;++i) #define per(i,j,k) for(i=j;i>=k;--i) #define sqr(x) ((x)*(x)) #define G getchar() #define LL long long #define pii pair<int,int> #define mkp make_pair #define X first #define Y second int c[510005][26],n,id,sz[510005],cnt;LL ans; char s[510005];bool dg[510005]; vector<int>v[510005]; void ins(){ int x=1,ch,i; per(i,strlen(s)-1,0){ int &y=c[x][ch=s[i]-'a']; if(!y)y=id++; x=y; } dg[x]=1; } void DFS0(int x,int an){ int i,y; if(dg[x]){ v[an].push_back(x);an=x; } rep(i,0,25)if(y=c[x][i]) DFS0(y,an); } void DFS1(int x){ sz[x]=1; vector<int>::iterator ii; for(ii=v[x].begin();ii!=v[x].end();++ii){ DFS1(*ii);sz[x]+=sz[*ii]; } } bool cmp(int x,int y){ return sz[x]<sz[y]; } void DFS2(int x,int an){ if(x>1){ans+=++cnt-an;an=cnt;} sort(v[x].begin(),v[x].end(),cmp); vector<int>::iterator ii; for(ii=v[x].begin();ii!=v[x].end();++ii) DFS2(*ii,an); } int main(){ // freopen("r.in","r",stdin); // freopen("w.out","w",stdout); int i; scanf("%d",&n);id=2; while(n--){ scanf("%s",s); ins(); } DFS0(1,1);DFS1(1);DFS2(1,0); printf("%lld\n",ans); return 0; }
相关文章推荐
- 【BZOJ 4567】【SCOI 2016】背单词
- bzoj 4567: [Scoi2016]背单词
- bzoj 4567: [Scoi2016]背单词
- 4567: [Scoi2016]背单词
- 【bzoj 4567】[Scoi2016]背单词 trie树+贪心
- BZOJ 4567: [Scoi2016]背单词
- 4567: [Scoi2016]背单词
- bzoj 4567: [Scoi2016]背单词 字典树+贪心
- 【BZOJ 4567】【SCOI 2016】背单词
- 4567: [Scoi2016]背单词 trie+贪心
- 4567: [Scoi2016]背单词
- 4567: [Scoi2016]背单词
- BZOJ 4567: [Scoi2016]背单词
- [bzoj4567][Scoi2016][背单词] (贪心+trie树)
- Trie——BZOJ4567/Luogu3294 [Scoi2016]背单词
- [SCOI 2016]背单词
- bzoj4567 [Scoi2016]背单词
- BZOJ4567: [Scoi2016]背单词
- BZOJ4567: [Scoi2016]背单词
- 【bzoj4567】[Scoi2016]背单词