新做法求 Hack
查看原帖
新做法求 Hack
758416
Yun_Mengxi楼主2024/7/22 20:12

大概思路:先搜出直径,然后将直径上的边的权赋为 00,然后从任意端点再搜一下最长链,将直径的长度加上最长链的长度的和就是答案

代码:

#include <bits/stdc++.h>

using namespace std;

const int kMaxN = 2e5 + 5;

struct Node {
	int v, w, nxt;
} e[kMaxN << 1];

int n;
int dis, x;
int res, a, b, c;
int hd[kMaxN], cnt = 1;
vector<pair<int, int>> stk, d;

void add(int u, int v) {
	e[++cnt].nxt = hd[u];
	hd[u] = cnt;
	e[cnt].v = v;
	e[cnt].w = 1;
}

void dfs(int u, int fa, int s) {
	if (s >= dis) {
		dis = s;
		if (u != a && u != b && u != c) {
			x = u;
			d = stk;
		}
	}
	for (int i = hd[u]; i; i = e[i].nxt) {
		int v = e[i].v, w = e[i].w;
		if (v == fa) {
			continue;
		}
		stk.push_back({u, i});
		dfs(v, u, s + w);
		stk.pop_back();
	}
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n;
	for (int i = 1, a, b; i < n; i++) {
		cin >> a >> b;
		add(a, b);
		add(b, a);
	}
	dis = 0;
	dfs(1, 0, 0);
	a = x;
	dis = 0;
	dfs(x, 0, 0);
	b = x;
//	cout << dis << '\n';
	res += dis;
	dis = 0;
	for (auto i : d) {
//		cout << i.first << ' ' << e[i.second].v << '\n';
		e[i.second].w = e[i.second ^ 1].w = 0;
	}
	dfs(x, 0, 0);
	c = x;
//	cout << dis << '\n';
//	for (auto i : d) {
//		cout << i.first << ' ' << e[i.second].v << ' ' << e[i.second].w << '\n';
//	}
	res += dis;
	cout << res << '\n' << a << ' ' << b << ' ' << c << '\n';
	return 0;
}

看了一遍题解区,好像没有这种做法,请问这种做法假没假啊?

最好是给一组 Hack,悬 2 关

2024/7/22 20:12
加载中...