• 资格赛:题目1:同构


    时间限制:2000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    给定2个树A和B,保证A的节点个数>=B的节点个数。

    现在你需要对树A的边进行二染色。

    一个好的染色方案,指不存在一个树A中的连通块,同时满足以下2个条件

    1. 其中只有同色的边

    2. 和B同构。两个树同构是指,存在一个一一映射(既是单射又是满射),将树B的各节点映射到不同的树A的节点,使得原来在树B中相邻的点,在映射后,仍相邻。

    问是否存在一种好的染色方案。

    输入

    第一行一个整数T (1<=T<=10),表示数据组数。

    接下来是T组输入数据,测试数据之间没有空行。

    每组数据格式如下:

    第一行一个整数N ,表示树A的节点总数。

    接下来N-1行,每行2个数a, b (1 <= a, b <= N)表示树A的节点a和b之间有一条边。

    接下来一行,一个整数M(1 <= M <= N),表示树B的节点总数。

    接下来M-1行,每行2个数a, b (1 <= a, b <= M)表示树B的节点a和b之间有一条边。

    输出

    对每组数据,先输出“Case x: ”,x表示是第几组数据,然后接“YES”/“NO”,表示是否存在所求的染色方案。

    数据范围

    小数据:1 <= N <= 20

    大数据:1 <= N <= 1000000

    样例解释

    无论如何染色,只要从A中挑一条边就行了。

    样例输入
    1
    3
    1 2
    2 3
    2
    1 2
    
    样例输出
    Case 1: NO

    题目解析:

    1. 两棵树 A , B ; node(A) >= node(B) ;对 A 二染色,与 B 同构部分不能只有一种颜色。

    2.问题转化为:对 A 二染色,颜色相同的部分不能与 B 同构。

    3. 举例:

                      

                                          A                                ————————————>         B’

                                                                              由 A 得出最大边同色树

    其中,A 的根结点的度最大为 5 , 则它连接的边必定有 3 条相同(无论如何染色)。而那些与根节点不相关的边,可以任意染色。

    若 B 是 B’ 的子树,则答案是 "NO";否则,答案是 "YES"。

    由此图,得出样例输入 && 输出:

    1

    12

    1 2

    1 3

    ……

    5 12

    4

    1 2

    1 3

    1 4

    Case 1: NO

    4:解题思路:在树 A 中,找出度最大(设为 D)的节点,进而求出树 B’ (1个根节点,(D+1)/2 个叶节点,深度为 1);

                      判断 B 是否是 B’ 的子树,若是,则  "NO",否     则 "YES"。 

    code:

     1 #include<stdio.h>
     2 #include<memory.h>
     3 const int MAX = 1e+6 +1;
     4 int d1[MAX];
     5 int d2[MAX];
     6 int main(){
     7     int T, M, N;
     8     scanf("%d",&T);
     9     for(int k = 0; k < T; ++k){
    10         memset(d1, 0, sizeof(d1));
    11         memset(d2, 0, sizeof(d2));
    12         int v1, v2;
    13         scanf("%d", &N);
    14         for(int i = 1; i < N; ++i){
    15             scanf("%d%d", &v1, &v2);
    16             ++d1[v1]; ++d1[v2];
    17         }
    18         scanf("%d", &M);
    19         for(int i = 1; i < M; ++i){
    20             scanf("%d%d", &v1, &v2);
    21             ++d2[v1]; ++d2[v2];
    22         }
    23         int D = 0, Mleaf = 0;
    24         for(int i = 1; i <= N; ++i){
    25             if(d1[i] > D) D = d1[i];
    26             if(d2[i] == 1) ++Mleaf;
    27         }
    28         if(M < 3) --Mleaf; // remove root Node 
    29         if(Mleaf == M - 1 && Mleaf <= (D + 1) / 2)
    30             printf("Case %d: NO
    ", k+1);
    31         else printf("Case %d: YES
    ", k+1);
    32     }
    33     return 0;
    34 }
     
     
  • 相关阅读:
    Elasticsearch搜索引擎学习笔记(二)
    Elasticsearch搜索引擎学习笔记(一)
    Redis集群(cluster模式)搭建(三主三从)
    Redis主从、哨兵
    oracle 数据查询 返回树形结构的每一级的id
    oracle 数据库查询 COALESCE字符函数
    java 生成不重复的6位数字 +年月日
    oracle 数据库查询CLOB类型 报错 【ORA-00932: 数据类型不一致: 应为 -, 但却获得 CLOB】
    oracle 数据表结构和数据 导入 导出
    sql 创建数据库表结构
  • 原文地址:https://www.cnblogs.com/liyangguang1988/p/3664434.html
Copyright © 2020-2023  润新知