zoukankan      html  css  js  c++  java
  • uoj problem 11 ydc的大树

    题目大意:

    给定一颗黑白树.允许删除一个白点.最大化删点后无法与删点前距自己最远的黑点连通的黑点个数.并求出方案数.

    题解:

    这道题很棒棒啊.

    一开始想了一个做法,要用LCT去搞,特别麻烦而且还是(O(nlogn))

    % 了vfk的题解才知道这道题居然是(O(n))的...


    我们有一个结论:一个点到其最远点的路径一定经过树的直径的重心.

    因为所有直径的重心一定相同,所以我们知道重心最多有两个,并且一定连续.

    所以我们将重心提至根,以新的根重新建树.那么我们现在就可以发现我们要切断的所有路径一定都经过根.

    所以我们考虑枚举删除的白点.其子树当中的所有黑点所连出的路径一定都被切断

    那么我们现在考虑计算除这些子树外的路径.

    对于同处于根的同一个儿子中的其他的黑点一定无法被切断.

    这时我们要讨论一下我们当前的枚举点是否处于到根路径前2大的黑点所在的路径.

    如果是,那么我们仍需要讨论一下这个路径是否全由这个以这个点为根的子树更新来.

    然后再瞎XX判一些东西即可.(不具体说是什么是因为说不清楚...还不懂的话自己YY吧)

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    inline void read(int &x){
        x=0;char ch;bool flag = false;
        while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
        while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    const int maxn = 100010;
    struct Edge{
        int to,next,dis;
    }G[maxn<<1];
    int head[maxn],cnt,rt;
    void add(int u,int v,int d){
        G[++cnt].to = v;
        G[cnt].next = head[u];
        head[u] = cnt;
        G[cnt].dis = d;
    }
    bool col[maxn];
    int f[maxn],g[maxn],pos;
    #define v G[i].to
    void dfs(int u,int f,int *dis){
        if(col[u] && dis[pos] < dis[u]) pos = u;
        for(int i = head[u];i;i=G[i].next){
    	if(v == f) continue;
    	dis[v] = dis[u] + G[i].dis;
    	dfs(v,u,dis);
        }
    }
    int belong[maxn],siz[maxn];
    void dfs2(int u,int fa,int d){
        if(fa == rt) belong[u] = u;
        else belong[u] = belong[fa];
        siz[u] = col[u];
        for(int i = head[u];i;i=G[i].next){
    	if(v == fa) continue;
    	dfs2(v,u,d+G[i].dis);
    	siz[u] += siz[v];
        }
        if(siz[u]){
    	f[u] = d;g[u] = 1;
    	for(int i = head[u];i;i=G[i].next){
    	    if(v == fa) continue;
    	    if(f[v] > f[u]){
    		f[u] = f[v];
    		g[u] = g[v];
    	    }else if(f[v] == f[u]) g[u] += g[v];
    	}
        }
    }
    #undef v
    int main(){
        int n,m;read(n);read(m);
        for(int i=1,x;i<=m;++i){
    	read(x);col[x] = true;
        }
        for(int i=1,u,v,d;i<n;++i){
    	read(u);read(v);read(d);
    	add(u,v,d);add(v,u,d);
        }
        pos = 0;dfs(1,1,f);
        int x = pos;pos = 0;
        dfs(x,x,g);
    
        memset(f,0,sizeof f);
        dfs(pos,pos,f);
        rt = 0;
        for(int i=1;i<=n;++i){
    	if(f[i] + g[i] == f[x]){
    	    if(rt == 0) rt = i;
    	    else if(abs(f[i] - g[i]) < abs(f[rt] - g[rt])) rt = i;
    	}
        }
        memset(f,0,sizeof f);
        memset(g,0,sizeof g);
        dfs2(rt,rt,0);
        int mx = 0,cmx = 0,mxid = 0,cmxid = 0;
        for(int i = head[rt];i;i=G[i].next){
    	int v = G[i].to;
    	if(siz[v] == 0) continue;
    	if(f[v] > mx){
    	    cmx = mx;cmxid = mxid;
    	    mx = f[v];mxid = v;
    	}else if(f[v] == mx){
    	    if(mx == cmx){
    		mxid = cmxid = 0;
    		break;
    	    }else{
    		cmx = mx;cmxid = mxid;
    		mx = f[v];mxid = v;
    	    }
    	}else if(f[v] > cmx){
    	    cmx = f[v];
    	    cmxid = v;
    	}
        }
        int ans = 0,ans_cnt = 0;
        if(col[rt] == false) ans = m,ans_cnt = 1;
        for(int i = 1;i<=n;++i){
    	if(i == rt || col[i]) continue;
    	int res = siz[i];
    	if(siz[i]&&(f[i] == f[belong[i]])&&(g[i] == g[belong[i]])){
    	    if(belong[i] == mxid){
    		if(f[mxid] > f[cmxid]) res += m - siz[mxid];
    		else res += siz[cmxid];
    	    }else if(belong[i] == cmxid) res += siz[mxid];
    	}
    	if(res > ans) ans = res,ans_cnt = 1;
    	else if(res == ans) ++ ans_cnt;
        }
        printf("%d %d
    ",ans,ans_cnt);
        return 0;
    }
    
    
    
  • 相关阅读:
    云计算下一浪潮,腾讯云抢占 Serverless 制高点
    Serverless + GitHub Actions 完美自动化部署静态网站
    Serverless 技术在格灵深瞳的落地实践
    万物皆可 Serverless 之我的 Serverless 之路
    LeetCode 哈希表 136:只出现一次的数字(计数哈希表,异或)
    Spring 01 IOC
    LeetCode 数组:1.两数之和 11. 盛最多水的容器
    LeetCode 链表:21合并两个有序链表 19删除链表的倒数第N个节点
    Maybatis的一些总结(三:增删改查)
    Maybatis的一些总结(一:了解)
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6636850.html
Copyright © 2011-2022 走看看