zoukankan      html  css  js  c++  java
  • CodeForces

    题目大意:

      一棵树 n个点 有m个点被标记 求经过所有被标记的点的最短路径的长度以及起点(如有多条输出编号最小的起点)。

    思路:

      1.当且仅当一个点本身或其子树中有点被标记时该点在最短的路径上因此,可以将多余的点删去,得到新的一棵树。
      2.不难发现,新树上的边必定被经过一次或两次,而且当只经过一次的边的集合为树的直径时,路径最短。

    反思:

      “如有多条输出编号最小的起点”是个坑点,要在最远的点中找出编号最小的当端点。

    代码:

     1 #include<cstdio>
     2 #define u v[i]
     3 const int M=250000;
     4 int s,a[M],v[M],hea[M],nex[M];
     5 bool b[M];
     6 
     7 int read()
     8 {
     9     int x=0; char ch=getchar();
    10     while (ch<48 || ch>57) ch=getchar();
    11     while (ch>47 && ch<58) x=(x<<1)+(x<<3)+ch-48,ch=getchar();
    12     return x;
    13 }
    14 
    15 void add(int x,int y) { v[++s]=y,nex[s]=hea[x],hea[x]=s; }
    16 
    17 void dfs(int x,int p)
    18 {
    19     for (int i=hea[x];i;i=nex[i])
    20         if (u^p) dfs(u,x),b[x]|=b[u];
    21 }
    22 
    23 void DFS(int x,int y,int p)
    24 {
    25     a[x]=y;
    26     for (int i=hea[x];i;i=nex[i])
    27         if (b[u] && u^p) DFS(u,y+1,x);
    28 }
    29 
    30 int main()
    31 {
    32     int n=read(),m=read(),i,x,y;
    33     for (i=1;i<n;++i) x=read(),y=read(),add(x,y),add(y,x);
    34     for (i=b[y=read()]=1;i<m;++i) b[read()]=1;
    35     for (dfs(y,0),a[0]=s=-1,i=1;i<=n;++i) s=s+b[i];
    36     for (DFS(y,x=0,0),i=1;i<=n;++i)
    37         if (b[i] && a[x]<a[i]) x=i;
    38     for (DFS(x,y=0,0),i=1;i<=n;++i)
    39         if (b[i] && a[y]<a[i]) y=i;
    40     printf("%d
    %d
    ",x<y?x:y,s+s-a[y]);
    41     return 0;
    42 }
  • 相关阅读:
    keyCode的使用
    写自已的类库需要的核心代码
    50个必备的实用jQuery代码段
    javascript基础
    给js原生Array增加each方法
    jquery中一些容易让人困惑的东西总结[转载]
    ajax编程
    oracle的正则表达式 [转载]
    eclipse 插件大全
    SlickGrid Options
  • 原文地址:https://www.cnblogs.com/HHshy/p/7189548.html
Copyright © 2011-2022 走看看