Codeforces Round 934 (Div. 2) ---- E - Tree Compass --- 题解

目录

E - Tree Compass:

题目大意:

思路解析:

 代码实现:


 



E - Tree Compass

E - Tree Compass:

题目大意:

思路解析:

 我们要使所花的次数尽可能少,等价于我们每次删除的结点尽可能多,那我们就看这样删除有啥性质,是否真的等价。

 

 

如果我们将直径为一的树和直径为2的树都看作特例的话。可以发现直径为奇数的树 需要 (d+1) / 2次, 直径为偶数的树 需要 (d / 2 - 1) * 2 次并且找不到更加有效的删除方案。

 代码实现:

import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Main {
    static int inf = (int) 2e7;
    static Vector<Integer>[] g;
    static Vector<Integer> path;


    public static void main(String[] args) throws IOException {

        int t = f.nextInt();
        while (t > 0) {
            solve();
            t--;
        }

        w.flush();
        w.close();
        br.close();
    }

    public static void solve() {
        int n = f.nextInt();
        g = new Vector[n + 1];
        path = new Vector<>();
        for (int i = 0; i < n + 1; i++) {
            g[i] = new Vector<>();
        }
        for (int i = 0; i < n - 1; i++) {
            int x = f.nextInt();
            int y = f.nextInt();
            g[x].add(y);
            g[y].add(x);
        }
        dfs(1, 0);
        ArrayList<int[]> res = new ArrayList<>();
        int len = path.size();
        if (len % 2 == 1){
            int x = path.get(len / 2);
            for (int i = 0; i <= len / 2; i++) {
                res.add(new int[]{x, i});
            }
        }else {
            int x = path.get(len / 2);
            int y = path.get(len / 2 - 1);
            for (int i = len / 2 - 1; i >= 0; i-=2) {
                res.add(new int[]{x, i});
                res.add(new int[]{y,i});
            }
        }

        w.println(res.size());
        for (int[] a1 : res) {
            w.println(a1[0] + " " + a1[1]);
        }

    }

    static Vector<Integer> dfs(int x, int fa) {
        Vector<Integer> d1 = new Vector<>();
        Vector<Integer> d2 = new Vector<>();
        for (int i = 0; i < g[x].size(); i++) {
            int y = g[x].get(i);
            if (y == fa) continue;
            Vector<Integer> d = dfs(y, x);
            if (d.size() > d1.size()) {
                d2 = d1;
                d1 = d;
            } else if (d.size() > d2.size()) d2 = d;
        }
        d1.add(0, x);
        if (d1.size() + d2.size() > path.size()) {
            path = d2;
            for (Integer a : d1) {
                path.add(0, a);
            }
        }
        return d1;
    }

    static PrintWriter w = new PrintWriter(new OutputStreamWriter(System.out));
    static Input f = new Input(System.in);
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    static class Input {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public Input(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public String nextLine() {
            String str = null;
            try {
                str = reader.readLine();
            } catch (IOException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
            return str;
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public Double nextDouble() {
            return Double.parseDouble(next());
        }

        public BigInteger nextBigInteger() {
            return new BigInteger(next());
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Studying~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值