QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#124062#5439. Meet in the MiddleTadijaSebezWA 7ms27100kbC++143.9kb2023-07-14 05:34:352023-07-14 05:34:36

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-07-14 05:34:36]
  • 评测
  • 测评结果:WA
  • 用时:7ms
  • 内存:27100kb
  • [2023-07-14 05:34:35]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back

const int N=100050;
const int L=18;
const ll inf=1e18;

struct CentroidTree{
	vector<pair<int,int>> E[N];
	bool was[N],clean[N];
	int sz[N],cenPar[N],cenDep[N];
	ll dep[N][L];
	ll mx[N];

	vector<int> dirty;

	CentroidTree(){
		for(int i=0;i<N;i++){
			was[i]=false;
			sz[i]=0;
			cenPar[i]=0;
			cenDep[i]=0;
			for(int j=0;j<L;j++){
				dep[i][j]=0;
			}
			E[i].clear();
		}
		dirty.clear();
	}

	void AddEdge(int u,int v,int w){
		E[u].pb({v,w});
		E[v].pb({u,w});
	}

	void DFSSZ(int u,int p){
		sz[u]=1;
		for(auto e:E[u]){
			int v=e.first;
			if(!was[v]&&v!=p){
				DFSSZ(v,u);
				sz[u]+=sz[v];
			}
		}
	}

	int Find(int u,int p,int n){
		for(auto e:E[u]){
			int v=e.first;
			if(!was[v]&&v!=p&&sz[v]*2>=n){
				return Find(v,u,n);
			}
		}
		return u;
	}

	int Find(int u){
		DFSSZ(u,u);
		return Find(u,u,sz[u]);
	}

	void DFSDEP(int u,int p,int lvl,ll w){
		dep[u][lvl]=w;
		for(auto e:E[u]){
			int v=e.first;
			if(!was[v]&&v!=p){
				DFSDEP(v,u,lvl,w+e.second);
			}
		}
	}

	void Build(int u=1, int lvl=0){
		u=Find(u);
		was[u]=true;
		cenDep[u]=lvl;
		mx[u]=-inf;
		clean[u]=true;
		for(auto e:E[u]){
			int v=e.first;
			if(!was[v]){
				DFSDEP(v,u,lvl,e.second);
			}
		}
		for(auto e:E[u]){
			int v=e.first;
			if(!was[v]){
				Build(v,lvl+1);
				cenPar[v]=u;
			}
		}
	}

	void Set(int u,ll w){
		for(int cen=u;cen;cen=cenPar[cen]){
			mx[cen]=max(mx[cen],w+dep[u][cenDep[cen]]);
			if(clean[cen]){
				clean[cen]=false;
				dirty.pb(cen);
			}
		}
	}

	void Reset(){
		for(int u:dirty){
			clean[u]=true;
			mx[u]=-inf;
		}
		dirty.clear();
	}

	ll Get(int u){
		ll ans=-inf;
		for(int cen=u;cen;cen=cenPar[cen]){
			ans=max(ans,mx[cen]+dep[u][cenDep[cen]]);
		}
		return ans;
	}
};

CentroidTree tree;

vector<pair<int,int>> E[N];
vector<pair<int,int>> Qs[N];
ll ans[N];
bool was[N];
int sz[N];

void DFSSZ(int u,int p){
	sz[u]=1;
	for(auto e:E[u]){
		int v=e.first;
		if(!was[v]&&v!=p){
			DFSSZ(v,u);
			sz[u]+=sz[v];
		}
	}
}

int Find(int u,int p,int n){
	for(auto e:E[u]){
		int v=e.first;
		if(!was[v]&&v!=p&&sz[v]*2>=n){
			return Find(v,u,n);
		}
	}
	return u;
}

int Find(int u){
	DFSSZ(u,u);
	return Find(u,u,sz[u]);
}

void DFSDEP(int u,int p,int lvl,ll w){
	tree.Set(u,w);
	for(auto e:E[u]){
		int v=e.first;
		if(!was[v]&&v!=p){
			DFSDEP(v,u,lvl,w+e.second);
		}
	}
}

void Solve(int u,int p,int lvl,ll w){
	for(auto q:Qs[u]){
		//printf("u:%i v:%i lvl:%i w:%lld get:%lld\n",u,q.first,lvl,w,tree.Get(q.first));
		ans[q.second]=max(ans[q.second],tree.Get(q.first)+w);
	}
	for(auto e:E[u]){
		int v=e.first;
		if(!was[v]&&v!=p){
			Solve(v,u,lvl,w+e.second);
		}
	}
}

void Decompose(int u,int lvl=0){
	u=Find(u);
	was[u]=true;
	tree.Set(u,0);
	for(auto e:E[u]){
		int v=e.first;
		if(!was[v]){
			Solve(v,u,lvl,e.second);
			DFSDEP(v,u,lvl,e.second);
		}
	}

	for(auto q:Qs[u]){
		//printf("u:%i v:%i lvl:%i w:%lld get:%lld\n",u,q.first,lvl,0,tree.Get(q.first));
		ans[q.second]=max(ans[q.second],tree.Get(q.first));
	}
	tree.Reset();

	reverse(E[u].begin(),E[u].end());

	tree.Set(u,0);
	for(auto e:E[u]){
		int v=e.first;
		if(!was[v]){
			Solve(v,u,lvl,e.second);
			DFSDEP(v,u,lvl,e.second);
		}
	}
	tree.Reset();

	for(auto e:E[u]){
		int v=e.first;
		if(!was[v]){
			Decompose(v,lvl+1);
		}
	}
}

int main(){
	int n,q;
	scanf("%i %i",&n,&q);
	for(int i=1;i<n;i++){
		int u,v,w;
		scanf("%i %i %i",&u,&v,&w);
		tree.AddEdge(u,v,w);
	}
	tree.Build();
	for(int i=1;i<n;i++){
		int u,v,w;
		scanf("%i %i %i",&u,&v,&w);
		E[u].pb({v,w});
		E[v].pb({u,w});
	}
	for(int i=1;i<=q;i++){
		int u,v;
		scanf("%i %i",&u,&v);
		Qs[v].pb({u,i});
		ans[i]=-inf;
	}
	Decompose(1);
	for(int i=1;i<=q;i++){
		printf("%lld\n",ans[i]);
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 7ms
memory: 27100kb

input:

3 4
1 2 1
2 3 2
1 2 2
2 3 1
1 1
1 2
2 1
2 2

output:

6
4
5
3

result:

ok 4 number(s): "6 4 5 3"

Test #2:

score: 0
Accepted
time: 0ms
memory: 26488kb

input:

2 1
1 2 1
1 2 1
1 1

output:

2

result:

ok 1 number(s): "2"

Test #3:

score: -100
Wrong Answer
time: 0ms
memory: 26436kb

input:

2 1
1 2 1
1 2 1
1 2

output:

3

result:

wrong answer 1st numbers differ - expected: '1', found: '3'