[字典树 最小树形图] Codeforces Gym 100307 NEERC 13 D. Dictionary
来源:互联网 发布:好看的校园网络电影 编辑:程序博客网 时间:2024/05/22 17:21
先把所有串建成字典树 字典树上的边 边权为1
然后如果两个点 一个是另一个的后缀 那么就另一个向那一个连0的边
跑一通最小树形图就好了 我不会 拷了个板子
输出方案就很蛋疼了
#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>using namespace std;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline int read(char *s){ char c=nc(); int len=0; for (;!(c>='a' && c<='z');c=nc()); for (;c>='a' && c<='z';s[++len]=c,c=nc()); s[++len]=0; return len-1;}const int INF=0x3f3f3f3f; const int maxn=1000005; int m; struct Edge { int u,v,cost,id,ru,rv,rcost; }edge[maxn]; int _u[maxn],_v[maxn];void add_Edge(int id,int u,int v,int c) { edge[id].id=id; edge[id].u=edge[id].ru=u; edge[id].v=edge[id].rv=v; edge[id].cost=edge[id].rcost=c; _u[id]=u; _v[id]=v;} int pre[maxn],id[maxn],vis[maxn],in[maxn]; //// !!!! int preid[maxn],useE[maxn]; int eA[maxn],eD[maxn]; int ex; int zhuliu(int root,int n,int m) { int ex=m,res=0; while(true) { for(int i=0;i<n;i++) in[i]=INF; for(int i=0;i<m;i++) { if(edge[i].u!=edge[i].v&&edge[i].cost<in[edge[i].v]) { pre[edge[i].v]=edge[i].u; in[edge[i].v]=edge[i].cost; //// !!!! preid[edge[i].v]=edge[i].id; } } for(int i=0;i<n;i++) if(i!=root&&in[i]==INF) return -1; int tn=0; memset(id,-1,sizeof(id)); memset(vis,-1,sizeof(vis)); in[root]=0; for(int i=0;i<n;i++) { res+=in[i]; int v=i; //// !!!! if(i!=root) useE[preid[i]]++; while(vis[v]!=i&&id[v]==-1&&v!=root) { vis[v]=i; v=pre[v]; } if(v!=root&&id[v]==-1) { for(int u=pre[v];u!=v;u=pre[u]) id[u]=tn; id[v]=tn++; } } if(tn==0) break; for(int i=0;i<n;i++) if(id[i]==-1) id[i]=tn++; for(int i=0;i<m;i++) { int v=edge[i].v; edge[i].u=id[edge[i].u]; edge[i].v=id[edge[i].v]; if(edge[i].u!=edge[i].v) { edge[i].cost-=in[v]; //// !!!! eA[ex]=edge[i].id; eD[ex]=preid[v]; edge[i].id=ex; ex++; } } n=tn; root=id[root]; } //// !!!! for(int i=ex-1;i>=m;i--) { if(useE[i]) { useE[eA[i]]++; useE[eD[i]]--; } } return res; } const int N=55;int n;char s[N][15]; int len[N];const int M=5005;int ncnt=1;int fat[M]; char c[M];int ch[M][26];inline void Ins(char *s,int n){ int p=1; for (int i=1;i<=n;i++){ if (!ch[p][s[i]-'a']) ch[p][s[i]-'a']=++ncnt,fat[ncnt]=p,c[ncnt]=s[i]; p=ch[p][s[i]-'a']; }}inline string Str(int p){ string s; while (p!=1) s=c[p]+s,p=fat[p]; return s;}inline bool Jud(string a,string b){ if (b.length()>a.length()) return 0; int s=a.length()-b.length(); for (int i=0;i<b.length();i++) if (a[s+i]!=b[i]) return 0; return 1;}int Pre[M];int _fat[M];inline int Fat(int u){ return u==_fat[u]?u:_fat[u]=Fat(_fat[u]);}int w[M][M];int idx[M];int main(){ freopen("dictionary.in","r",stdin); freopen("dictionary.out","w",stdout); scanf("%d",&n); ncnt=1; for (int i=1;i<=n;i++) len[i]=read(s[i]),Ins(s[i],len[i]); for (int i=0;i<ncnt;i++) for (int j=0;j<ncnt;j++) w[i][j]=1<<30; for (int i=2;i<=ncnt;i++) add_Edge(m++,fat[i]-1,i-1,2),w[fat[i]-1][i-1]=1; for (int i=2;i<=ncnt;i++) for (int j=2;j<=ncnt;j++) if (i!=j && Jud(Str(i),Str(j))) add_Edge(m++,i-1,j-1,1),w[i-1][j-1]=0; int ans=zhuliu(0,ncnt,m)+1; for (int i=0;i<m;i++) if (useE[i]&&edge[i].rcost) Pre[_v[i]+1]=_u[i]+1; for (int i=1;i<=ncnt;i++) _fat[i]=i; for (int i=2;i<=ncnt;i++) if (w[Pre[i]-1][i-1]==0) _fat[Fat(i)]=Pre[i]; int tot=0; for (int i=1;i<=ncnt;i++) if (Fat(i)==i) idx[i]=++tot; printf("%d\n",tot); printf("0\n"); for (int i=2;i<=ncnt;i++) if (Fat(i)==i) printf("%d %c\n",idx[Fat(fat[i])],c[i]); return 0;}
0 0
- [字典树 最小树形图] Codeforces Gym 100307 NEERC 13 D. Dictionary
- [交互 杂题] Codeforces Gym 100307 NEERC 13 I. Interactive Interception
- codeforces gym 2016-2017 NEERC, Moscow Subregional K. Knights of the Old Republic 最小生成树+dp
- [三分套三分] Codeforces Gym 100307 NEERC 13 E. Easy Geometry
- [仙人掌同构 Hash] Codeforces Gym 100307 NEERC 13 C. Cactus Automorphisms
- [树形DP 费用流手动增广] Codeforces Gym 101190 NEERC 16 M. Mole Tunnels
- [费用流建模] Codeforces Gym 101190 NEERC 16 D. Delight for a Cat
- Codeforces Gym 101190 (NEERC 2016) A. Abbreviation
- UVALive 5913 【NEERC 2011 D】 Dictionary Size
- Codeforces Gym 100203D Different vectors 最小表示法
- CodeForces Gym 100735D
- UVALive 6674 Dictionary AC自动机+最小树形图+输出最小树形图
- [物理 杂题] Codeforces Gym 101190 NEERC 16 J. Jenga Boom
- [博弈论] Codeforces Gym 101190 NEERC 16 G. Game on Graph
- [杂题] Codeforces Gym 101190 NEERC 16 K. Kids Designing Kids
- [构造] Codeforces Gym 101190 NEERC 16 C. Cactus Construction
- [杂题] Codeforces Gym 101190 NEERC 16 L. List of Primes
- [构造] Codeforces Gym 100553 NEERC 14 E. Epic Win!
- 获得训练集和XML通过opencv自带程序opencv_createsamples.exe&opencv_traincascade.exe的问题
- c++输入输出总结
- 集合框架-Collection集合-2
- sprintf()和itoa()的区别
- maven setting.xml配置
- [字典树 最小树形图] Codeforces Gym 100307 NEERC 13 D. Dictionary
- android studio快捷键
- 用JS获取地址栏参数的方法(超级简单)
- java 中 静态块的作用
- C++ 中include头文件时尖括号<>与双引号""的区别
- 解决MetInfo(米拓)5.3版本后伪静态无法正常使用的问题
- Spring MVC No converter found for return value of type 解决方法
- ubuntu进行apt-get时候出现Package ssh is not available, but is referred to by another package 错误
- [Leetcode] 91. Decode Ways 解题报告