60pts求调
查看原帖
60pts求调
1088873
Tanliu楼主2024/10/22 21:47

交完之后,看了看TJ,思路应该是相似的,但就是调不出来,求巨佬帮调

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
typedef long long ll;
using namespace std;
const int N=5e4+5,M=21,INF=1e10;
int n,m,army[N],siz[N],fa[N][M+1],ans[N],where[N],dis[N],vis[N],change[N],ff[N],II[N],baba[N],CHECK[N],cnt;
struct node{
	int v,w;
};
vector<node>h[N];
void dfs(int u,int fat){
	if(fat!=-1)fa[u][0]=fat;
	for(int i=1;i<=M;i++)fa[u][i]=fa[fa[u][i-1]][i-1];
	int fla=0;
	for(int i=0;i<h[u].size();i++){
		int v=h[u][i].v,w=h[u][i].w;
		if(v==fat)continue;
		fla=1;
		dis[v]=dis[u]+w;
		dfs(v,u);
		siz[u]=siz[u]+siz[v];
		ans[u]+=ans[v]+w;
	}
	ans[0]=max(ans[0],ans[u]);
	if(fla==0)siz[u]=1;
}
struct poi{
	int v,fat;
};
queue<poi>q;
priority_queue<int,vector<int>,greater<int> >q1,q2;
bool check(int time){
	for(int i=1;i<=n;i++)vis[i]=change[i]=II[i]=baba[i]=0;
	for(int i=1;i<=m;i++){
		where[i]=army[i];
		for(int j=M;j>=0;j--){
			if(where[i]==1)break;
			if(dis[army[i]]-dis[fa[where[i]][j]]<=time&&fa[where[i]][j]!=0)where[i]=fa[where[i]][j];
		}
		if(where[i]==1)II[i]=1;
	}
	for(int i=1;i<=m;i++)vis[where[i]]=1;
	q.push({1,-1});
	while(!q.empty()){
		int u=q.front().v,fat=q.front().fat;
		q.pop();
		for(int i=0;i<h[u].size();i++){
			int v=h[u][i].v,w=h[u][i].w;
			if(v==fat)continue;
			if(vis[v]==1)change[ff[v]]+=siz[v];
			else q.push({v,u});
		}
	}
//	for(int i=1;i<=m;i++){
//		if(change[ff[i]]!=siz[ff[i]]&&II[i]==1){
//			if(dis[baba[ff[i]]]<dis[i]){
//				CHECK[i]=1;
//				CHECK[baba[ff[i]]]=0;
//				baba[ff[i]]=i;
//			}
//		}
//	}
	for(int i=1;i<=m;i++)printf("%d ",II[i]);printf("\n");
	for(int i=1;i<=m;i++)printf("%d: %d\n",army[i],where[i]);printf("\n");
	for(int i=0;i<h[1].size();i++)printf("%d: %d\n",h[1][i].v,baba[h[1][i].v]);printf("\n");
	while(!q1.empty())q1.pop();
	while(!q2.empty())q2.pop();
	printf("---");
	for(int i=0;i<h[1].size();i++){
		int v=h[1][i].v,w=h[1][i].w;
		if(change[v]<siz[v]/*&&baba[v]==0*/){
			printf("%d ",v);
			q1.push(w);
		}
	}printf("\n");
	for(int i=1;i<=m;i++){
		if(where[i]==1/*&&CHECK[i]==0*/){
			q2.push(time-dis[army[i]]);
		}
	}
	while(!q1.empty()){
		while(!q2.empty()&&q1.top()>q2.top())q2.pop();
		if(q2.empty()){
			printf("false\n");
			return false;
		}
		q1.pop();q2.pop();
	}
	if(q1.empty()){printf("true\n");return true;}
	printf("false\n");
	return false;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<n;i++){
		int u,v,value;
		scanf("%d %d %d",&u,&v,&value);
		h[u].push_back({v,value});
		h[v].push_back({u,value});
	}
	scanf("%d",&m);
	if(m<h[1].size()){printf("%d",-1);return 0;}
	for(int i=1;i<=m;i++)scanf("%d",&army[i]);
	dfs(1,-1);
	for(int i=2;i<=n;i++){
		int u=i;
		for(int j=M;j>=0;j--)if(fa[u][j]>1)u=fa[u][j];
		ff[i]=u;
	}
//	check(100);return 0;
	int l=0,r=ans[0]*2;
	while(r-l>1){
		int mid=(l+r)/2;
//		printf("---%d\n",mid);
		if(check(mid))r=mid;
		else l=mid;
	}
	printf("%d",r);
	return 0;
}
/*
4
1 2 99
1 3 1
1 4 99
3
3 4 4

*/
2024/10/22 21:47
加载中...