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

      

  • 相关阅读:
    Java实现 计蒜客 拯救行动
    Java实现 计蒜客 拯救行动
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 173 二叉搜索树迭代器
    Java实现 LeetCode 173 二叉搜索树迭代器
    Visual Studio的SDK配置
    怎样使用CMenu类
    mfc menu用法一
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9474044.html
Copyright © 2011-2022 走看看