zoukankan      html  css  js  c++  java
  • [CF592D]Super M

    题目大意:
    给定一颗n个节点树,边权为1,树上有m个点被标记,问从树上一个点出发,经过所有被标记的点的最短路程,以及可行的最小的端点编号。(起终点自选)
    M<=N<=123456

    思路:
    随便定一个标记节点为根,然后以该节点开始遍历,将不是标记节点的叶节点剪掉,剩下的边数为P。求出树的直径L。答案即为2*P-L。
    另外注意一定要保证节点编号最小。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<vector>
     4 #include<algorithm>
     5 inline int getint() {
     6     int ch;
     7     while(!isdigit(ch=getchar()));
     8     int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int N=123457,inf=0x7fffffff;
    13 int n,m;
    14 bool a[N]={0};
    15 struct Edge {
    16     int to;
    17     bool cut;
    18 };
    19 std::vector<Edge> e[N];
    20 inline void add_edge(const int u,const int v) {
    21     e[u].push_back((Edge){v,false});
    22     e[v].push_back((Edge){u,false});
    23 }
    24 int u=inf,x=inf,v=inf,l=0;
    25 void find_u(const int x,const int parent,const int depth) {
    26     if(depth>l) {
    27         l=depth;
    28         u=x;
    29     }
    30     else if(depth==l) {
    31         u=std::min(u,x);
    32     }
    33     for(unsigned int i=0;i<e[x].size();i++) {
    34         if(e[x][i].to==parent||e[x][i].cut) continue;
    35         find_u(e[x][i].to,x,depth+1);
    36     }
    37 }
    38 void find_v(const int x,const int parent,const int depth) {
    39     if(depth>l) {
    40         l=depth;
    41         v=x;
    42     }
    43     else if(depth==l) {
    44         v=std::min(v,x);
    45     }
    46     for(unsigned int i=0;i<e[x].size();i++) {
    47         if(e[x][i].to==parent||e[x][i].cut) continue;
    48         find_v(e[x][i].to,x,depth+1);
    49     }
    50 }
    51 bool cut(const int x,const int parent) {
    52     bool ret=true;
    53     for(unsigned int i=0;i<e[x].size();i++) {
    54         if(e[x][i].to==parent) continue;
    55         if(cut(e[x][i].to,x)) {
    56             e[x][i].cut=true;
    57             n--;
    58         }
    59         else {
    60             ret=false;
    61         }
    62     }
    63     return ret&&!a[x];
    64 }
    65 int main() {
    66     n=getint()-1,m=getint();
    67     for(int i=0;i<n;i++) add_edge(getint(),getint());
    68     int x=inf;
    69     for(int i=0;i<m;i++) {
    70         int t=getint();
    71         a[t]=true;
    72         x=std::min(x,t);
    73     }
    74     cut(x,0);
    75     find_u(x,0,0);
    76     find_v(u,0,0);
    77     printf("%d
    %d
    ",std::min(u,v),(n<<1)-l);
    78     return 0;
    79 }
  • 相关阅读:
    DataTable轉EXCEL 3/21
    中風預防知識
    unable to convert mysql date/time value to system.data.time 11/14
    win8 获得地理坐标 GIS
    页面嵌套 GIS
    win8 metro 弹出一个部分 GIS
    正则表达式基础 之 ? GIS
    windows phone pivot 开发过程中的使用心得 GIS
    线程不安全 GIS
    线程基础知识 GIS
  • 原文地址:https://www.cnblogs.com/skylee03/p/7141930.html
Copyright © 2011-2022 走看看