zoukankan      html  css  js  c++  java
  • HDU

    http://acm.hdu.edu.cn/showproblem.php?pid=4607

    题意

    一颗n个顶点的树,现在只想访问其中k个,问最短路径长度为多少。

    分析

    首先,最短的路径当然是一条链。那么我们需要求树的直径。求法:先从任意一点dfs到最深处v,再以v为根深搜,得到的最长路径便是树的直径。

    若k小于等于直径,那么这k个顶点肯定是处于直径路径上最优,此时答案为k-1。

    若k大于直径,即需要走不在直径上的点。根据大量实践发现,每个不在直径上的点对答案的贡献都是2。因此最终答案就是k-1+(k-d)*2

    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<algorithm>
    #include<map>
    #include<set>
    #include<stack>
    #define rep(i,e) for(int i=0;i<(e);i++)
    #define rep1(i,e) for(int i=1;i<=(e);i++)
    #define repx(i,x,e) for(int i=(x);i<=(e);i++)
    #define X first
    #define Y second
    #define PB push_back
    #define MP make_pair
    #define mset(var,val) memset(var,val,sizeof(var))
    #define scd(a) scanf("%d",&a)
    #define scdd(a,b) scanf("%d%d",&a,&b)
    #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
    #define pd(a) printf("%d
    ",a)
    #define scl(a) scanf("%lld",&a)
    #define scll(a,b) scanf("%lld%lld",&a,&b)
    #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
    #define IOS ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    typedef long long ll;
    template <class T>
    void test(T a){cout<<a<<endl;}
    template <class T,class T2>
    void test(T a,T2 b){cout<<a<<" "<<b<<endl;}
    template <class T,class T2,class T3>
    void test(T a,T2 b,T3 c){cout<<a<<" "<<b<<" "<<c<<endl;}
    const int N = 1e6+10;
    //const int MAXN = 210;
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3fll;
    const ll mod = 1000000007;
    int T;
    void testcase(){
        printf("Case #%d: ",++T);
    }
    const int MAXN = 1e5+5;
    const int MAXM = 30;
    
    struct Edge{
        int to,nxt;
    }edge[MAXN<<1];
    
    int n,m,cnt,head[MAXN];
    int dis[MAXN];
    
    void init(){
        cnt=0;
        mset(head,-1);
    }
    void addedge(int u,int v){
        edge[cnt].to=v;
        edge[cnt].nxt=head[u];
        head[u]=cnt++;
    }
    
    void DFS(int u){
        for(int i=head[u];i!=-1;i=edge[i].nxt){
            int v=edge[i].to;
            if(dis[v]==-1){
                dis[v]=dis[u]+1;
                DFS(v);
            }
        }
    }
    
    int main(){
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif // LOCAL
        int t;
        scanf("%d",&t);
        while(t--){
            init();
            scdd(n,m);
            int u,v;
            for(int i=1;i<n;i++){
                scdd(u,v);
                addedge(u,v);
                addedge(v,u);
            }
            mset(dis,-1);
            dis[1]=0;
            DFS(1);
            int len=0;
            for(int i=1;i<=n;i++)
                if(dis[i]>len){
                    len=dis[i];
                    u=i;
                }
            mset(dis,-1);
            dis[u]=0;
            DFS(u);
            len=0;
            for(int i=1;i<=n;i++)
                if(dis[i]>len)
                    len=dis[i];
            len++;
            int k;
            while(m--){
                scanf("%d",&k);
                if(len>=k)
                    cout<<k-1<<endl;
                else
                    cout<<(len-1)+(k-len)*2<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    pytest知识梳理
    linux服务器时间不同步解决
    python re 多行匹配模式
    nginx--知识梳理
    tomcat--知识梳理
    利用springboot 重定向到静态资源功能,下载一些文件文件
    调试C++代码内存释放,在VS2019控制台显示内存泄露
    C++Primer第五版 第九章 习题9.22
    nginx 配置中间证书
    云苍穹消息推送代码
  • 原文地址:https://www.cnblogs.com/fht-litost/p/9281827.html
Copyright © 2011-2022 走看看