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;
    }
    

      

  • 相关阅读:
    Python中变量的作用域
    Python中关于函数的介绍
    python列表中的赋值与深浅拷贝
    Python中关于集合的介绍及用法
    python中文件操作的六种模式及对文件某一行进行修改的方法
    python中文件操作的其他方法
    python中文件操作的基本方法
    python中字符串的一些用法
    python里字典的用法介绍
    小谈python里 列表 的几种常用用法
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9474044.html
Copyright © 2011-2022 走看看