社区讨论

AC on #2,#3,#7 求调

P2495【模板】虚树 / [SDOI2011] 消耗战参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mm7s9ylt
此快照首次捕获于
2026/03/01 21:26
上周
此快照最后确认于
2026/03/04 19:30
5 天前
查看原帖
rt, record,
CPP
#include <algorithm>
#include <iostream>
#include <stack>
#define int long long 
using namespace std;
const int N = 2.5e5 + 5;
const int inf = 1e18;
int n, m, k;
int sc[N];
bool isSource[N];
struct Graph {
	struct Edge {
		int u, v, w, next;
		void clear() {
			u = v = w = next = 0;
		}
		void output() {
			printf("Path %d %d %d %d\n", u, v, w, next);
		}
	} e[N * 2];
	int head[N], cur = 0;
	void add(int u, int v, int w) {
		e[++cur] = Edge{u, v, w, head[u]};
		head[u] = cur;
	}
	void Tree(int root, int fa, int dep) {
		for(int i = 1; i <= dep; i++) printf(" ");
		printf("%d\n", root);
		for(int i = head[root]; i; i = e[i].next) {
			if(e[i].v == fa) continue;
			Tree(e[i].v, root, dep + 1);
		}
	}
} O, T;
int Log[N], Fa[N][30];
int dep[N], dfn[N], fa[N], path[N], DFN = 0;
void dfs1(int u, int f, int de) {
	fa[u] = f; Fa[u][0] = f; dep[u] = de; dfn[u] = ++DFN;
	for(int i = O.head[u]; i; i = O.e[i].next) {
		int v = O.e[i].v;
		if(v == f) continue;
		path[v] = min(path[u], O.e[i].w); 
		dfs1(v, u, de + 1);
	}
}
int st[N], top = 0;
int lowbit(int x) {
	return x & (-x);
}
int LCA(int u, int v) {
	if(dep[u] < dep[v]) swap(u, v);
	for(int ddep = dep[u] - dep[v]; ddep; ddep -= lowbit(ddep))
		u = Fa[u][Log[lowbit(ddep)]];
	if(u == v) return u;
	for(int i = Log[n]; i >= 0; i--) {
		if(Fa[u][i] == Fa[v][i]) continue;
		u = Fa[u][i], v = Fa[v][i];
	}
	return fa[u];
}
bool cmp(int u, int v) {
	return dfn[u] < dfn[v];
}
int dfs2(int u, int f) {
	int res = 0;
	for(int i = T.head[u]; i; i = T.e[i].next) {
		res += dfs2(T.e[i].v, u);
	}
	if(isSource[u]) res = path[u];
	else res = min(path[u], res);
	isSource[u] = 0;
	T.head[u] = 0;
	return res;
}
void Solve() {
	T.cur = 0; 
	scanf("%lld", &k);
	for(int i = 1; i <= k; i++) {
		scanf("%lld", &sc[i]);
		isSource[sc[i]] = 1;
	}
	sort(sc + 1, sc + k + 1, cmp);
	top = 0;
	st[0] = 0; st[++top] = sc[1];
	for(int i = 2; i <= k; i++) {
		int now = sc[i];
		int lca = LCA(now, st[top]);
		while(1) {
			if(lca == st[top]) {
				break;
			} else if(dep[st[top]] > dep[lca] && dep[lca] > dep[st[top - 1]]) {
				T.add(lca, st[top], 1);
				st[top] = lca;
				break;
			} else if(lca == st[top - 1]) {
				T.add(lca, st[top], 1);
				top--;
				break;
			} else {
				T.add(st[top - 1], st[top--], 1);
			}
		}
		st[++top] = now;
	}
	int root = st[1];
	for(int i = 1; i < top; i++) {
		T.add(st[i], st[i + 1], 1);
		st[i] = 0;
	}
	printf("%lld\n", dfs2(root, 0));
}
signed main() {
	scanf("%lld", &n);
	for(int i = 1; i < n; i++) {
		int u, v, w;
		scanf("%lld%lld%lld", &u, &v, &w);
		O.add(u, v, w);
		O.add(v, u, w);
	}
	path[1] = inf;
	dfs1(1, 0, 1);
	Log[1] = 0;
	for(int i = 2; i <= n; i++) Log[i] = Log[i / 2] + 1;
	for(int i = 1; i <= Log[n]; i++)
		for(int j = 1; j <= n; j++)
			Fa[j][i] = Fa[Fa[j][i - 1]][i - 1];
	scanf("%lld", &m);
	while(m--) Solve();
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...