zoukankan      html  css  js  c++  java
  • hdu 4607 ( Park Visit )

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

    题目大意就是给你N个点和N-1条边,保证整个图连通(因为边的限制,所以不可能形成环),每条边长度唯一,问要到达K个点的最短路径(起点任意)。

    这题画了好久的图,当时就是想找最长链,任意起点,然后BFS找到最远的点,然后从最远的点再进行BFS找最远的点,那么这两个点就是最长链的两个端点,由于图是联通的,手N-1条边的限制,所以一定是一棵树,而且要到达K个点也就好球了当K>n时,所以是要到最长路的分支上去的。而且取得点一定是去了还要回来到最长链上。结果也就出来了。

    后来虎哥说这个最长链就是树的直径。上网搜了一下

    这是摘得别人的

    from -> Roba

    怒赞roba


    树的直径(Diameter)是指树上的最长简单路。
    直径的求法:两遍BFS (or DFS)
    任选一点u为起点,对树进行BFS遍历,找出离u最远的点v
    以v为起点,再进行BFS遍历,找出离v最远的点w。则v到w的路径长度即为树的直径
    *简单证明
    于是原问题可以在O(E)时间内求出

    关键在于证明第一次遍历的正确性,也就是对于任意点u,距离它最远的点v一定是最长路的一端。
    如果u在最长路上,那么v一定是最长路的一端。可以用反证法:假设v不是最长路的一端,则存在另一点v’使得(u→v’)是最长路的一部分,于是len(u→v’) > len(u→v)。但这与条件“v是距u最远的点”矛盾。
    如果u不在最长路上,则u到其距最远点v的路与最长路一定有一交点c,且(c→v)与最长路的后半段重合(why?),即v一定是最长路的一端

    因为是树是连通的,所以u必有一条路径c和最长路径L相交,len(c)>=1,L被分为两部分,一部分l1,一部分l2
    假设第一次dfs过后,所求最长路径lu端不在L上,那么len(lu)>=len(c)+len(l1)(l1,l2对称,取l1或者l2都一样)
    len(l2+c+lu)>len(l1+l2),矛盾.


    虽然是挖坟,不过分享知识更重要,呵呵  

    代码

    #include <string.h>
    #include <iostream>
    #include <cstdio>
    #include <stdlib.h>
    #include <vector>
    #include <queue>
    using namespace std;
    const int maxn = 100050;
    
    
    vector <int> g[maxn];
    
    struct node
    {
        int s,point;
    };
    
    int vis[maxn];
    struct node bfs(int s)
    {
        memset(vis,0,sizeof(vis));
        queue <struct node>q;
        q.push((node){0,s});
        vis[s] = 1;
        struct node max;
        max.s = 0;
    
        while(!q.empty())
        {
            struct node now,temp;
            now = q.front();
            q.pop();
            int i;
            for(i = 0;i < g[now.point].size();i++)
            {
                int v = g[now.point][i];
                temp.s = now.s+1;
                temp.point = v;
                if(!vis[v])
                {
                    vis[v] = 1;
                  //  cout<<v<<"***"<<endl;
    
                    if(max.s < temp.s)
                    max = temp;
                    q.push(temp);
                }
            }
        }
        return max;
    }
    int main()
    {
    
         int t;
         scanf("%d",&t);
         while (t--)
         {
             int n,m;
             scanf("%d %d",&n,&m);
             int i;
             for(i = 1;i <= n;i++)
             g[i].clear();
             for(i = 1;i < n;i++)
             {
                 int a,b;
                 scanf("%d %d",&a,&b);
                 g[a].push_back(b);
                 g[b].push_back(a);
             }
             struct node max;
             max = bfs(1);
             max = bfs(max.point);
    
             for(i = 0;i < m;i++)
             {
                 int k;
                 scanf("%d",&k);
                 if(k <= max.s+1)
                 printf("%d
    ",k-1);
                 else
                 {
                     printf("%d
    ",(k-max.s-1)*2+max.s);
                 }
             }
         }
        return 0;
    }
  • 相关阅读:
    设计模式----工厂模式
    设计模式----简单工厂
    log4net使用详解
    link/Extended dependency 无法显示连接
    Abp框架之执行Update-Database 命令系列错误
    Index API
    使用Java客户端操作elasticsearch(二)
    elasticsearch之分词插件使用
    使用Java Low Level REST Client操作elasticsearch
    js如何获取隐藏的元素的高度
  • 原文地址:https://www.cnblogs.com/0803yijia/p/3209371.html
Copyright © 2011-2022 走看看