zoukankan      html  css  js  c++  java
  • [CF911F]Tree Destruction

    题目大意:给你一棵树,每次挑选这棵树的两个叶子,把答案加上他们之间的距离,然后将其中一个点去掉,问你距离之和最大可以是多少。要求输出方案

    题解:求出直径和直径上的点,因为树上一个点可以提供的最大贡献为它到直径中的一个端点的距离,于是把不在直径上的点先删去(注意要按深度一个个删,因为要求删叶子)。

    卡点:1.没有按深度从大到小删,删除了非叶子节点

      2.爆$long;long$

    C++ Code:

    #include <cstdio>
    #include <cstring>
    #define maxn 200010
    #define int long long
    using namespace std;
    int head[maxn], cnt;
    struct Edge {
    	int to, nxt;
    } e[maxn << 1];
    void add(int a, int b) {
    	e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
    }
    int n, x, y;
    int depx[maxn], depy[maxn], fa[maxn];
    int q[maxn], h, t;
    int ans, v[maxn], tot;
    bool isd[maxn];
    inline int max(int a, int b) {return a > b ? a : b;}
    int bfs(int rt, int *dep) {
    	q[h = t = 0] = rt;
    	while (h <= t) {
    		int u = q[h++];
    		for (int i = head[u]; i; i = e[i].nxt) {
    			int v = e[i].to;
    			if (!dep[v]) {
    				fa[v] = u;
    				dep[v] = dep[u] + 1;
    				q[++t] = v;
    			}
    		}
    	}
    	return q[t];
    }
    void up(int rt) {
    	isd[rt] = true;
    	v[tot++] = rt;
    	while (rt != y) {
    		rt = fa[rt];
    		v[tot++] = rt;
    		isd[rt] = true;
    	}
    }
    signed main() {
    	scanf("%I64d", &n);
    	for (int i = 1; i < n; i++) {
    		int a, b;
    		scanf("%I64d%I64d", &a, &b);
    		add(a, b);
    		add(b, a);
    	}
    	if (n == 1) {puts("0"); return 0;}
    	if (n == 2) {puts("1"); puts("1 2 1"); return 0;}
    	depx[1] = 1; x = bfs(1, depx);
    	memset(depx, 0, sizeof depx);
    	depx[x] = 1; y = bfs(x, depx);
    	depy[y] = 1; bfs(y, depy);
    	up(x);
    	for (int i = 1; i <= n; i++) {
    		if (!isd[i]) ans += max(depx[i], depy[i]) - 1;
    		else ans += depy[i] - 1;
    	}
    	printf("%I64d
    ", ans);
    	for (int i = t; ~i; i--) {
    		if (!isd[q[i]]){
    			if (depx[q[i]] > depy[q[i]]) printf("%I64d %I64d %I64d
    ", x, q[i], q[i]);
    			else printf("%I64d %I64d %d
    ", y, q[i], q[i]);
    		}
    	}
    	for (int i = 0; i < tot - 1; i++) printf("%I64d %I64d %I64d
    ", y, v[i], v[i]);
    	return 0;
    }
    

      

  • 相关阅读:
    CSS盒子模型
    getContextPath、getServletPath、getRequestURI、request.getRealPath的区别
    MYSQL中的CASE WHEN END AS
    单点登录的精华总结
    git&github
    June 21st 2017 Week 25th Wednesday
    June 20th 2017 Week 25th Tuesday
    June 19th 2017 Week 25th Monday
    June 18th 2017 Week 25th Sunday
    June 17th 2017 Week 24th Saturday
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9474044.html
Copyright © 2011-2022 走看看