目录
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());
}
}
}