首页 新闻 会员 周边

P17834求调

0
悬赏园豆:5 [待解决问题]

15pts.
洛谷没人给我调,我相信这里会有好人。

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N=5e6+1;

int c,tc,t,n,k,u,v,deg[N],DEG[N],q[N],in_core[N],h[N];
vector<int>E[N];
bool vis[N];

void peel(int dep){
    int l=1,r=0;
	for(int i=1;i<=n;i++)
        deg[i]=DEG[i]=E[i].size(),in_core[i]=h[i]=0;
    for(int i=1;i<=n;i++)
        if(DEG[i]<=1)
            in_core[i]=1,q[++r]=i;
    int now_dep=1;
    while(l<=r&&now_dep<dep){
        int u=q[l++];
        for(auto v:E[u]){
            if(DEG[v]<=1)
                continue;
            DEG[v]--;
            if(DEG[v]==1&&!in_core[v]){
            	h[v]=max(h[v],in_core[u]+1);
                in_core[v]=in_core[u]+1,q[++r]=v;
			}
        }
        ++now_dep;
    }
}

bool solve_on_the_chain(vector<int>chain,int del){
	int len=chain.size();
	if(len<del)
		return true;
	deque<int>q1,q2;
	for(int i=0;i<len;i++){
		int u=chain[i];
		int val1=h[u]+i;
		while(!q1.empty()&&(h[chain[q1.back()]]+q1.back())<=val1)
			q1.pop_back();
		int val2=h[u]-i;
		while(!q2.empty()&&(h[chain[q2.back()]]-q2.back())<=val2)
			q2.pop_back();
		q1.push_back(i),q2.push_back(i);
		if(i>=del-1){
			int L=i-del+1,R=i;
			while(!q1.empty()&&q1.front()<L)
				q1.pop_front();
			while(!q2.empty()&&q2.front()<L)
				q2.pop_front();
			int Left=h[chain[q1.front()]]+q1.front(),Right=h[chain[q2.front()]]-q2.front();
			if(Left<=R+del&&Right<=R-L)
				return true;
		}
	}
	return false;
}

bool check(int rad){
    peel(rad);
    int cnt=0;
    for(int i=1;i<=n;i++)
        if(!in_core[i])
            cnt++;
    if(cnt<=k)
        return true;
    int rem=cnt-k;
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=n;i++){
        if(!in_core[i]||deg[i]>2||vis[i])
            continue;
        int pre=0,start=i;
        vector<int>chain;
        while(true){
            int nxt=-1;
            for(int v:E[start])
                if(!in_core[v]&&deg[v]<=2&&v!=pre){
                    nxt=v;
                    break;
                }
            if(nxt==-1)
                break;
            pre=start,start=nxt;
        }
		pre=0,u=start;
        while(u!=0){
            vis[u]=true,chain.push_back(u);
            int nxt=0;
            for(int v:E[u])
                if(!in_core[v]&&deg[v]<=2&&v!=pre){
                    nxt=v;
                    break;
                }
            pre=u,u=nxt;
        }
        if(solve_on_the_chain(chain,rem))
        	return true;
    }
    return false;
}

void solve(){
	for(int i=1;i<=n;i++)
		E[i].clear();
	cin>>n>>k;
	for(int i=1;i<n;i++)
		cin>>u>>v,E[u].push_back(v),E[v].push_back(u);
	if(n==k){
		cout<<0<<endl;
		return;
	}
	int l=1,r=n,ans=n;
	while(l<=r){
		int mid=(l+r)>>1;
		if(check(mid))
			r=mid-1,ans=mid;
		else
			l=mid+1;
	}
	cout<<ans<<endl;
}

int main(){
	cin>>c>>tc;
	while(tc--)
		solve();
}
yuyancheng的主页 yuyancheng | 菜鸟二级 | 园豆:235
提问于:2026-11-12 13:02
<
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册。