点分治95pts求调,WAon7
查看原帖
点分治95pts求调,WAon7
448884
快乐的大童楼主2023/8/14 16:53

rt,写的是点分治的另一种写法(不用桶的做法)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<unordered_map>
#include<vector>
#include<queue>
#include<bitset>
#include<set>
#include<ctime>
#include<random>
#define x1 xx1
#define y1 yy1
#define IOS ios::sync_with_stdio(false)
#define ITIE cin.tie(0);
#define OTIE cout.tie(0);
#define PY puts("AYE")
#define PN puts("NAY")
#define PW puts("-1")
#define P__ puts("")
#define PU puts("--------------------")
#define popc __builtin_popcount
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define gc getchar
#define pc putchar
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define per(a,b,c) for(int a=b;a>=c;a--)
#define reprange(a,b,c,d) for(int a=b;a<=c;a+=d)
#define perrange(a,b,c,d) for(int a=b;a>=c;a-=d)
#define graph(i,j,k,l) for(int i=k[j];i;i=l[i].nxt)
#define lowbit(x) (x&-x)
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define mem(x,y) memset(x,y,sizeof x);
//#define int long long
//#define int __int128
using namespace std;
inline int rd(){
	int x=0,f=1;int ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}return x*f;
}
inline void write(int x,char ch='\0'){
	if(x<0){x=-x;putchar('-');}
	int y=0;char z[40];
	while(x||!y){z[y++]=x%10+48;x/=10;}
	while(y--)putchar(z[y]);if(ch!='\0')putchar(ch);
}
const int maxn=2e5+5,inf=0x7fffffff;
int n,m;
vector<pii>G[maxn];
int rt;
int siz[maxn];
bool vis[maxn];
int q[maxn];
int ans=inf;
struct node{
	int dis,edge,bel;
	bool operator<(const node &p)const{
		if(dis!=p.dis) return dis<p.dis;
		return edge<p.edge;
	}
}a[maxn];
int cnt;
void get_rt(int x,int y,int sum){
	bool flag=1;siz[x]=1;
	for(auto i:G[x]){
		int u=i.fi;
		if(u==y||vis[u]) continue;
		get_rt(u,x,sum);siz[x]+=siz[u];
		flag&=(siz[u]<=sum/2);
	}
	if(flag&&sum-siz[x]<=sum/2) rt=x;
}
map<int,int>noip[maxn];
queue<pii>noiq;
void get_dis(int x,int y,int dis,int bel,int edge){
	if(!noip[bel][dis]) noip[bel][dis]=inf;
	if(noip[bel][dis]==inf) noiq.push(mp(bel,dis));
	noip[bel][dis]=min(noip[bel][dis],edge);
	for(auto i:G[x]){
		int u=i.fi;
		if(u==y||vis[u]) continue;
		get_dis(u,x,dis+i.se,bel,edge+1);
	}
}
void calc(int x){
	cnt=0;
	a[++cnt].dis=0,a[cnt].edge=0,a[cnt].bel=x;
	for(auto i:G[x]){
		if(vis[i.fi])continue;
		get_dis(i.fi,x,i.se,i.fi,1);
	}
	while(!noiq.empty()){
		auto now=noiq.front();noiq.pop();
		a[++cnt].dis=now.se,a[cnt].bel=now.fi,a[cnt].edge=noip[now.fi][now.se];
		noip[now.fi][now.se]=inf;
	}
	sort(a+1,a+cnt+1);
	int l=1,r=cnt;
	while(l<r){
		if(a[l].dis+a[r].dis==m){
			if(a[l].bel!=a[r].bel) ans=min(ans,a[l].edge+a[r].edge);
			if(a[r].dis==a[r-1].dis) r--;
			else l++;
		}
		if(a[l].dis+a[r].dis<m) l++;
		else r--;
	}
}
void sol(int x,int sum){
	vis[x]=1;calc(x);
	get_rt(x,0,sum);
	for(auto i:G[x]){
		int u=i.fi;
		if(vis[u]) continue;
		get_rt(u,0,siz[u]);sol(rt,siz[u]);
	}
}
signed main(){
	n=rd(),m=rd();
	rep(i,1,n-1){
		int x=rd()+1,y=rd()+1,z=rd();
		G[x].push_back(mp(y,z)),G[y].push_back(mp(x,z));
	}
	get_rt(1,0,n);sol(rt,n);
	if(ans==inf)PW;else write(ans);
}
2023/8/14 16:53
加载中...