MnZn初学dfs,过了P4115,本题RE
查看原帖
MnZn初学dfs,过了P4115,本题RE
108111
Lumos壹玖贰壹楼主2021/12/20 10:51

RTRT,能过 样例 P4115P4115

如果是哪里 ntnt 了请轻喷

#include<bits/stdc++.h>
#define ri register int
#define ll long long
using namespace std;
const int maxn = 1e5 + 10,inf = 0x3f3f3f3f;
struct edge{
	int to,nex,w;
}e[maxn<<1];
struct heap{
	priority_queue<int> p,d;
	int size;
	inline void del(int x) {d.push(x);size--;}
	inline void push(int x) {p.push(x);size++;}
	inline void pre(){
		while(d.size() && d.top() == p.top())
			d.pop(),p.pop();
	}
	inline int top() {pre();return size ? p.top() : (-inf);}
	inline int getans() {
		if(!size) return -inf;
		if(size == 1) return 0;
		int x,y;
		x = top(); del(x); y = top(); push(x);
		return max(0,x + y);
	}
	inline void change(int x,int op) {op ? del(x) : push(x);}
}a[maxn],b[maxn],ans;
int n,q,co[maxn];
int head[maxn],top[maxn],fa[maxn],sz[maxn],son[maxn],dis[maxn],dep[maxn],tot;
int maxs[maxn],Fa[maxn],vis[maxn],size,rt;
inline int rd(){
	int res = 0,f = 0; char ch = getchar();
	for(;!isdigit(ch);ch = getchar()) if(ch == '-') f = 1;
	for(;isdigit(ch);ch = getchar()) res = (res<<3) + (res<<1) + ch - 48;
	return f ? -res : res;
}
inline void add(int u,int v,int w){
	e[++tot] = (edge){v,head[u],w};
	head[u] = tot;
}
void dfs1(int u,int f){
	fa[u] = f; sz[u] = 1;
	for(ri i = head[u];i;i = e[i].nex){
		int v = e[i].to;
		if(v == f) continue;
		dis[v] = dis[u] + e[i].w; dep[v] = dep[u] + 1;
		dfs1(v,u); sz[u] += sz[v];
		if(sz[v] > sz[son[u]]) son[u] = v;
	}
}
void dfs2(int u,int toop){
	top[u] = toop;
	if(son[u]) dfs2(son[u],toop);
	for(ri i = head[u];i;i = e[i].nex){
		int v = e[i].to;
		if(v == son[u] || v == fa[u]) continue;
		dfs2(v,v);
	}
}
inline int Dis(int u,int v){
	int res = dis[u] + dis[v];
	while(top[u] != top[v]){
		if(dep[top[u]] < dep[top[v]]) swap(u,v);
		u = fa[top[u]];
	}
	if(dep[u] > dep[v]) swap(u,v);
	res -= 2 * dis[u];
	return res;
}
void findrt(int u,int f){
	sz[u] = 1,maxs[u] = 0;
	for(ri i = head[u];i;i = e[i].nex){
		int v = e[i].to;
		if(v == f || vis[v]) continue;
		findrt(v,u);
		sz[u] += sz[v]; maxs[u] = max(maxs[u],sz[v]);
	}
	maxs[u] = max(maxs[u],size - sz[u]);
	if(maxs[u] < maxs[rt]) rt = u;
}
void dfs(int u,int f){
	if(Fa[rt]) a[rt].push(Dis(u,Fa[rt]));
	sz[u] = 1;
	for(ri i = head[u];i;i = e[i].nex){
		int v = e[i].to;
		if(vis[v] || v == f) continue;
		dfs(v,u); sz[u] += sz[v];
	}
}
void build(int u){
	vis[u] = 1; dfs(u,u); b[u].push(0);
	int nowrt;
	for(ri i = head[u];i;i = e[i].nex){
		int v = e[i].to;
		if(vis[v]) continue;
		rt = 0,size = sz[v],findrt(v,v);
		Fa[rt] = u; nowrt = rt;
		build(rt); b[u].push(a[nowrt].top());
	}
	ans.push(b[u].getans());
}
inline void modify(int u,int cl){
	int ans1,ans2,cur1,cur2;
	ans1 = b[u].getans(); b[u].change(0,cl); ans2 = b[u].getans();
	if(ans1 != ans2){
		if(ans1 != -inf) ans.del(ans1);
		if(ans2 != -inf) ans.push(ans2);
	}
	for(ri x = u;Fa[x];x = Fa[x]){
		int p = Fa[x];
		ans1 = a[x].top(); a[x].change(Dis(u,p),cl); ans2 = a[x].top();
		if(ans1 == ans2) continue;
		cur1 = b[p].getans();
		if(ans1 != -inf) b[p].del(ans1); if(ans2 != -inf) b[p].push(ans2);
		cur2 = b[p].getans(); 
		if(cur1 ^ cur2){
			if(cur1 != -inf) ans.del(cur1);
			if(cur2 != -inf) ans.push(cur2);
		}
	}
}
int main(){
	n = rd();
	for(ri i = 1,u,v,w;i < n;++i) u = rd(),v = rd(),w = rd(),add(u,v,w),add(v,u,w);
	dfs1(1,1); dfs2(1,1);
	rt = 0,maxs[0] = n + 1,size = n;
	findrt(1,1); build(rt);
	
	q = rd();
	char op; int u;
	while(q--){
		op = getchar();
		while(op != 'A' && op != 'C') op = getchar();
		if(op == 'A'){
			if(ans.size) printf("%d\n",ans.top());
			else puts("They have disappeared.");
		}
		else u = rd(),co[u] ^= 1,modify(u,co[u]);
	}
	return 0;
}

2021/12/20 10:51
加载中...