• 【codeforces 778C】 Peterson Polyglot


    http://codeforces.com/problemset/problem/778/C (题目链接)

    题意

      给出一个字典树,问删掉哪一层以后,得到的字典树最小。

    Solution

      直接对于每一层进行讨论启发式合并暴力搞就好了。复杂度证明真是玄学。

    细节

      注意根节点。

    代码

    // codeforces 778C
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define inf 2147483640
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    
    const int maxn=300010;
    int head[maxn],size[maxn],deep[maxn],c[maxn][26];
    int n,ans[maxn],cnt,sz;
    char ch[10];
    struct edge {int to,next;char w;}e[maxn<<1];
    
    void link(int u,int v) {
    	e[++cnt]=(edge){v,head[u],ch[0]};head[u]=cnt;
    	e[++cnt]=(edge){u,head[v],ch[0]};head[v]=cnt;
    }
    int merge(int a,int b) {
    	if (!a || !b) return a|b;
    	int x=++sz;size[x]=1;
    	for (int i=0;i<26;i++) {
    		c[x][i]=merge(c[a][i],c[b][i]);
    		size[x]+=size[c[x][i]];
    	}
    	return x;
    }
    void dfs(int x,int fa) {
    	size[x]=1;
    	for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa) {
    			deep[e[i].to]=deep[x]+1;
    			c[x][e[i].w-'a']=e[i].to;
    			dfs(e[i].to,x);
    			size[x]+=size[e[i].to];
    		}
    	ans[deep[x]]+=size[x];sz=n;
    	int p=0;
    	for (int i=0;i<26;i++) p=merge(p,c[x][i]);
    	ans[deep[x]]-=max(size[p],1);
    }
    int main() {
    	scanf("%d",&n);
    	for (int u,v,i=1;i<n;i++) {
    		scanf("%d%d%s",&u,&v,ch);
    		link(u,v);
    	}
    	dfs(1,0);
    	int res=0;
    	for (int i=0;i<n;i++) if (ans[i]>ans[res]) res=i;
    	printf("%d
    %d",n-ans[res],res+1);
    	return 0;
    }
    
  • 相关阅读:
    190401装饰器-高阶函数-闭包
    190329迭代器-生成器-三元运算-列表解析
    OpenStack-Mitaka
    RabbitMQ
    190328文件处理
    190322函数
    190322字符串
    190321集合
    190320运算符&数据类型
    Zookeeper
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/6471914.html
Copyright © 2020-2023  润新知