zoukankan      html  css  js  c++  java
  • [简单路径] Useful Decomposition

    Ramesses knows a lot about problems involving trees (undirected connected graphs without cycles)!

    He created a new useful tree decomposition, but he does not know how to construct it, so he asked you for help!

    The decomposition is the splitting the edges of the tree in some simple paths in such a way that each two paths have at least one common vertex. Each edge of the tree should be in exactly one path.

    Help Remesses, find such a decomposition of the tree or derermine that there is no such decomposition.


    Input

    The first line contains a single integer n

    (2n105

    ) the number of nodes in the tree.

    Each of the next n1

    lines contains two integers ai and bi (1ai,bin, aibi

    ) — the edges of the tree. It is guaranteed that the given edges form a tree.

    Output

    If there are no decompositions, print the only line containing "No".

    Otherwise in the first line print "Yes", and in the second line print the number of paths in the decomposition m

    .

    Each of the next m

    lines should contain two integers ui, vi (1ui,vin, uivi) denoting that one of the paths in the decomposition is the simple path between nodes ui and vi

    .

    Each pair of paths in the decomposition should have at least one common vertex, and each edge of the tree should be presented in exactly one path. You can print the paths and the ends of each path in arbitrary order.

    If there are multiple decompositions, print any.

    Examples
    Input
    4
    1 2
    2 3
    3 4
    Output
    Yes
    1
    1 4
    Input
    6
    1 2
    2 3
    3 4
    2 5
    3 6
    Output
    No
    Input
    5
    1 2
    1 3
    1 4
    1 5
    Output
    Yes
    4
    1 2
    1 3
    1 4
    1 5
    Note

    The tree from the first example is shown on the picture below: The number next to each edge corresponds to the path number in the decomposition. It is easy to see that this decomposition suits the required conditions.

    The tree from the second example is shown on the picture below: We can show that there are no valid decompositions of this tree.

    The tree from the third example is shown on the picture below: The number next to each edge corresponds to the path number in the decomposition. It is easy to see that this decomposition suits the required conditions.

     
    题意:给出n个结点成一颗树,问是否存在一些过一个公共结点的简单路径,如果存在则输出Yes并输出这些路径,否则输出No
    思路:简单路径就是在一个路径中同一个边只能出现一次.如果存在一些过一个公共结点的简单路径则最多只能有一个结点的度数大于2
    我们选一个度数最大的结点作为根结点,根结点到叶子结点的简单路径就是合法的简单路径,dfs求一下就完事了,然后就test5超时了.
    其实我们要输出根结点和叶子结点,而叶子结点是度数为1的结点,所以我们统计所有度数为1的结点,把它和根节点一起输出就好了
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<queue>
     5 #include<algorithm>
     6 using namespace std;
     7 typedef long long ll;
     8 const int amn=1e5+5;
     9 int n,ans,idx[amn],root;
    10 vector<int> eg[amn];
    11 struct node{
    12     int i,val;
    13 }cnt[amn];
    14 bool cmp(node a,node b){
    15     if(a.val==b.val)return a.i<b.i;
    16     return a.val>b.val;
    17 }
    18 int main(){
    19     scanf("%d",&n);
    20     int x,y;
    21     for(int i=1;i<=n-1;i++){
    22         scanf("%d%d",&x,&y);
    23         eg[x].push_back(y);
    24         eg[y].push_back(x);
    25     }
    26     for(int i=1;i<=n;i++){
    27         cnt[i].val=eg[i].size();
    28         cnt[i].i=i;
    29     }
    30     sort(cnt+1,cnt+1+n,cmp);
    31     if(cnt[1].val>2&&cnt[2].val>2){
    32         printf("No
    ");
    33     }
    34     else{
    35         if(cnt[1].val>2)root=cnt[1].i;
    36         else{
    37             for(int i=1;i<=n;i++){
    38                 if(cnt[i].val<2){
    39                     root=cnt[i].i;
    40                     break;
    41                 }
    42             }
    43         }
    44         memset(idx,0,sizeof idx);
    45         printf("Yes
    %d
    ",eg[root].size());
    46         int st;
    47         for(int i=n;i>=1;i--){
    48             if(cnt[i].val>1)break;
    49             st=i;
    50         }
    51         for(int i=st;i<=n;i++){
    52             if(cnt[i].i==root)continue;
    53             printf("%d ",root);
    54             printf("%d
    ",cnt[i].i);
    55         }
    56     }
    57 }
    58 /**
    59 题意:给出n个结点成一颗树,问是否存在一些过一个公共结点的简单路径,如果存在则输出Yes并输出这些路径,否则输出No
    60 思路:简单路径就是在一个路径中同一个边只能出现一次.如果存在一些过一个公共结点的简单路径则最多只能有一个结点的度数大于2
    61 我们选一个度数最大的结点作为根结点,根结点到叶子结点的简单路径就是合法的简单路径,dfs求一下就完事了,然后就test5超时了.
    62 其实我们要输出根结点和叶子结点,而叶子结点是度数为1的结点,所以我们统计所有度数为1的结点,把它和根节点一起输出就好了
    63 **/
  • 相关阅读:
    Linux虚拟机突然不能上网了
    项目经验不丰富、技术不突出的程序员怎么打动面试官?
    10分钟看懂!基于Zookeeper的分布式锁
    BATJ等大厂最全经典面试题分享
    分享30道Redis面试题,面试官能问到的我都找到了
    一个六年Java程序员的从业总结:比起掉发,我更怕掉队
    我是这样手写 Spring 的(麻雀虽小五脏俱全)
    自述:为什么一部分大公司还在采用过时的技术,作为技术人而言该去大公司还是小公司
    Java精选面试题之Spring Boot 三十三问
    Java程序员秋招面经大合集(BAT美团网易小米华为中兴等)
  • 原文地址:https://www.cnblogs.com/Railgun000/p/11827586.html
Copyright © 2011-2022 走看看