求调点分治90pts,TLE#4和#13
查看原帖
求调点分治90pts,TLE#4和#13
444063
Jessica2333楼主2024/7/22 20:12
#include<iostream>
#include<vector>
#include<map>
using namespace std;
struct ED{
	int v,w;
};
const int MAXV=1000000;
vector<ED> ed[200008];
int N,K,vis[200008],root,dep[200008],siz[200008],mxx[200008],hs[200008],dis[200008];
int mp[2000008];
int N2,ans=1000000;
void DFS0(int u,int father)
{
	for(auto it:ed[u])
	{
		int v=it.v,w=it.w;
		if(vis[v]||v==father) continue;
		dep[v]=dep[u]+1;
		dis[v]=dis[u]+w;
		DFS0(v,u);
	}
}
void get_root(int u,int father)
{
	siz[u]=1;
	hs[u]=N+1;
	for(auto it:ed[u])
	{
		int v=it.v;
		if(vis[v]||v==father) continue;
		get_root(v,u);
		siz[u]+=siz[v];
		if(hs[u]==N+1||siz[hs[u]]<siz[v]) hs[u]=v;
	}
	mxx[u]=max(siz[hs[u]],N2-siz[u]);
	if(root==N+1||mxx[root]>mxx[u]) root=u;
}
void calc(int u,int father)
{
	if(dis[u]==K) ans=min(ans,dep[u]);
	else if(dis[u]<K) ans=min(ans,dep[u]+mp[K-dis[u]]);
	else return ;
	for(auto it:ed[u])
	{
		int v=it.v,w=it.w;
		if(v==father||vis[v]) continue;
		calc(v,u);
	}
}
void add_(int u,int father,int tp)
{
	if(dis[u]>K) return ;
	if(tp==1) mp[dis[u]]=min(mp[dis[u]],dep[u]);
	else mp[dis[u]]=MAXV;
	for(auto it:ed[u])
	{
		int w=it.w,v=it.v;
		if(v==father||vis[u]) continue;
		add_(v,u,tp);
	}
}
void divide(int u)
{
	root=N+1;
//	DFS0(u,N+1);
	get_root(u,N+1);
	dep[root]=dis[root]=0;
	DFS0(root,N+1);
	u=root;
	for(auto it:ed[u])
	{
		int v=it.v;
		if(vis[v]) continue;
		calc(v,u);
		add_(v,u,1);
	}
	add_(u,N+1,0);
	vis[u]=1;
	for(auto it:ed[u])
	{
		int v=it.v;
		if(vis[v]) continue;
		N2=siz[v];
		divide(v);
	}
}
signed main()
{
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>N>>K;
	ans=MAXV;
	for(int i=1;i<N;i++)
	{
		int u,v,w;
		cin>>u>>v>>w;
		u++,v++;
		ed[u].push_back({v,w});
		ed[v].push_back({u,w});
	}
	for(int i=0;i<=MAXV;i++) mp[i]=MAXV;
	N2=N;divide(1);
	if(ans==MAXV) ans=-1;
	cout<<ans;
	return 0;
}
2024/7/22 20:12
加载中...