求助,后四个点WA了太弱调不出来
查看原帖
求助,后四个点WA了太弱调不出来
104381
hanmo0321楼主2020/10/28 20:08
#include<bits/stdc++.h>
using namespace std;
int n,m,edgenum,vet[100005],Next[100005],head[50005],len[100005],l,r,ans,cnt,dp[50005],d[50005],num,x;
bool vis[50005];
void addedge(int u,int v,int val){
	vet[++edgenum]=v;
	len[edgenum]=val;
	Next[edgenum]=head[u];
	head[u]=edgenum;
}
void dfs(int u,int fa){
	for(int e=head[u];e;e=Next[e]){
		int v=vet[e];
		if(v!=fa) dfs(v,u);
	}
	num=0;
	for(int e=head[u];e;e=Next[e]){
		int v=vet[e];
		if(v!=fa) d[++num]=dp[v]+len[e];
	}
	for(int i=1;i<=num;i++) vis[i]=0;
	sort(d+1,d+1+num);
	int now=1;
	for(int i=num;i>=1;i--)
		if(d[i]>=x) vis[i]=1,cnt++;
		else{
			int l=now,r=i-1,ans=-1;
			while(l<=r){
				int mid=(l+r)>>1;
				if(d[mid]+d[i]>=x) ans=mid,r=mid-1;
				else l=mid+1;
			}
			if(~ans) cnt++,vis[i]=vis[ans]=1,now=ans+1;
		}
	for(int i=1;i<=num;i++)
		if(!vis[i]) dp[u]=max(dp[u],d[i]);
	if(u==1){
		for(int i=num;i>1;i--)
			if(!vis[i] && !vis[i-1]) dp[u]=max(dp[u],d[i]+d[i-1]);
	}
}
bool check(){
	for(int i=1;i<=n;i++) dp[i]=0;
	cnt=0;
	dfs(1,-1);
	if(dp[1]>=x) cnt++;
	return cnt>=m;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<n;i++){
		int u,v,val;
		scanf("%d%d%d",&u,&v,&val);
		addedge(u,v,val);
		addedge(v,u,val);
		r+=val;
	}
	r/=m;
	while(l<=r){
		int mid=(l+r)>>1;
		x=mid;
		if(check()) ans=mid,l=mid+1;
		else r=mid-1;
	}
	printf("%d\n",ans);
	return 0;
} 

dp的过程是用二分写的,vis表示有没有被用作赛道,now是当前的左端点

2020/10/28 20:08
加载中...