社区讨论

求助二分tle原因

P5021[NOIP 2018 提高组] 赛道修建参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lo10eqcl
此快照首次捕获于
2023/10/22 13:09
2 年前
此快照最后确认于
2023/11/02 12:39
2 年前
查看原帖
代码:
CPP
#include<bits/stdc++.h>
using namespace std;
#pragma GCC optimize("Ofast")
typedef long long ll;
typedef pair<int,int> pii;
#define mk(a,b) make_pair((a),(b))
#define int ll

const int maxn=5e5+10;
const int inf=1e12;
const int mod=1e9+7;
int n,m,k,ans,sum=0;

struct node {
	int v,w;
};

vector<node> g[maxn];

inline int read() {
	int s=0,w=1;
	char ch=getchar();
	while(!isdigit(ch)) {
		if(ch=='-') w=-1;
		ch=getchar();
	}
	while(isdigit(ch)) s=s*10+ch-'0',ch=getchar();
	return s*w;
}

inline void write(int x) {
	if(x<0) x=-x,putchar('-');
	if(x>9) write(x/10);
	putchar('0'+x%10);
}

multiset<int> mset[maxn],tmp;
int num=0,val[maxn];

inline void dfs(int u,int fa,int len) {
	for(int i=0; i<g[u].size(); ++i) {
		int v=g[u][i].v,w=g[u][i].w;
		if(v==fa) continue;
		dfs(v,u,len);
		w+=val[v];	
		mset[u].insert(w);
	}
	while(!mset[u].empty()) {
		int k=*mset[u].begin();
		if(k>=len) {
			num++;
			mset[u].erase(mset[u].begin());
			continue;
		}
		auto it=mset[u].begin();
		it++;
		if(lower_bound(it,mset[u].end(),len-k)!=mset[u].end()) {
			auto nx=lower_bound(it,mset[u].end(),len-k);
			mset[u].erase(nx);
			num++;
		}
		tmp.insert(*mset[u].begin());
		mset[u].erase(mset[u].begin());
		// cout<<u<<' '<<k<<' '<<mset[u].size()<<endl;
	}
	if(!tmp.empty()) val[u]=*tmp.rbegin(),tmp.clear();
}

inline bool ok(int x) {
	num=0;
	for(int i=1;i<=n;++i) val[i]=0;
	dfs(1,1,x);
	return num>=k;
}

int dis[maxn],c;

inline void getd(int u,int fa) {
	for(int i=0;i<g[u].size();++i) {
		int v=g[u][i].v,w=g[u][i].w;
		if(v==fa) continue;
		dis[v]=dis[u]+w;
		if(dis[v]>dis[c]) c=v;
		getd(v,u);
	}
}

signed main() {
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n=read(),k=read();
	for(int i=1; i<n; ++i) {
		int u=read(),v=read(),w=read();
		g[u].push_back(node{v,w});
		g[v].push_back(node{u,w});
	}
	getd(1,0);
	dis[c]=0;
	getd(c,0);
	int l=1,r=dis[c],mid;
	while(l<=r) {
		mid=(l+r)>>1;
		if(ok(mid)) l=mid+1,ans=mid;
		else r=mid-1;
	}
	// dfs(1,1,7986);
	// cout<<num<<endl;
	write(ans);
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...