zoukankan      html  css  js  c++  java
  • 【luoguP3000】 [USACO10DEC]牛的健美操Cow Calisthenics

    题目链接

    二分答案,判断需要断几条边,用(f[i])表示以(i)为根的子树断边后的最长路径,对于一个点(u),存在(f[v]>mid)时就删到(v)的边(f[v1]+f[v2]>mid)时就删(f)较大的边,可以sort之后搞一搞

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    using namespace std;
    
    const int MAXN=100010;
    
    inline int read(){
    	int x=0; char c=getchar();
    	while(c<'0') c=getchar();
    	while(c>='0') x=x*10+c-'0',c=getchar();
    	return x;
    }
    
    int n,k;
    
    int Head[MAXN],num;
    struct NODE{
    	int to,nxt;
    }e[MAXN<<1];
    
    inline void add(int x,int y){
    	e[++num].to=y;
    	e[num].nxt=Head[x];
    	Head[x]=num;
    }
    
    int f[MAXN],Cnt,mid;
    
    inline bool cmp(int x,int y){
    	return x>y;
    }
    void dfs(int x,int fa){
    	vector<int> t; t.clear();
    	for(int i=Head[x];i;i=e[i].nxt){
    		int v=e[i].to;
    		if(v==fa) continue;
    		dfs(v,x);
    		t.push_back(f[v]+1);
    	}
    	if(!t.size()) return;
    	sort(t.begin(),t.end(),cmp);
    	int l=t.size(),i=0;
    	for(;i<l;++i)
    		if(t[i]>mid) ++Cnt;
    		else break;
    	for(;i+1<l;++i)
    		if(t[i]+t[i+1]>mid) ++Cnt;
    		else break;
    	f[x]=i<l?t[i]:0;
    }
    
    inline bool check(){
    	memset(f,0,sizeof(f));
    	Cnt=0;
    	dfs(1,0);
    	return Cnt<=k;
    }
    
    int main()
    {
    	scanf("%d%d",&n,&k);
    	int x,y;
    	for(int i=1;i<n;++i){
    		x=read(); y=read();
    		add(x,y); add(y,x);
    	}
    	int l=1,r=n;
    	while(l<r){
    		mid=(l+r)>>1;
    		if(check()) r=mid;
    		else l=mid+1;
    	}
    	printf("%d
    ",l);
    	return 0;
    }
    
  • 相关阅读:
    Spring MVC 复习笔记03
    Spring MVC 复习笔记02
    CSS之选择器
    Filedset
    Label标签
    Table标签
    列表标签
    CSS之img标签
    CSS之a标签锚点
    CSS之checkbox&radio&textarea&select
  • 原文地址:https://www.cnblogs.com/yjkhhh/p/11743692.html
Copyright © 2011-2022 走看看