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

      

  • 相关阅读:
    dumpsys
    阿里云云效流水线体验
    停车入场城市排行榜1
    第三方企业号对接工作
    PHP搭建(windows64+apache2.4.7+mysql-5.6+php5.5)
    十大编程算法助程序员走上高手之路
    数据库的最简单实现
    JavaScript 开发的45个经典技巧
    常用meta整理
    Shell脚本编程初体验
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9474044.html
Copyright © 2011-2022 走看看