• Anton and Tree


    Anton and Tree

    题目链接:http://codeforces.com/contest/734/problem/E

    DFS/BFS

    每一次操作都可以使连通的结点变色,所以可以将连通的点缩成一个点(由于Python的栈空间过小,这个操作只能用bfs;其他语言如c++可以直接dfs)。

    由于缩点后的树的结点是黑白相间的,将整棵树变成相同颜色的最小操作数为:在树的中点不断操作将整棵树变成相同颜色所需要的操作数,也就是整棵树的最大半径。

    求树的最大半径可以用一次dfs求得:

     1 def getAns(v):
     2     vis[v] = 1
     3     global ans
     4     m1, m2 = 0, 0
     5     for x in edge[v]:
     6         if vis[x] == 0:
     7             t = getAns(x)
     8             if t > m1:
     9                 m1, m2 = t, m1
    10             elif t > m2:
    11                 m2 = t
    12     ans = max(ans, m1 + m2 + 1)
    13     return m1 + 1
    View Code

    然而Python栈空间过小,只能考虑其他做法,这里使用的是两个bfs:

    第一个bfs找出以root为根的深度最大的结点u(树的直径两端的结点必有一个为此结点)

    第二次bfs找出以结点u为根的深度最大的结点v,此时v的深度则为树的直径

    代码如下:

     1 # import sys
     2 # sys.setrecursionlimit(1000000000)
     3 from collections import defaultdict, deque
     4 
     5 
     6 def buildTree(root):
     7     q = deque()
     8     q.append((root, root))
     9     vis = [0 for _ in range(n + 1)]
    10     vis[root] = 1
    11     while q:
    12         v, fa = q.pop()
    13         for x in preedge[v]:
    14             if vis[x] != 1:
    15                 vis[x] = 1
    16                 if col[x] == col[fa]:
    17                     q.append((x, fa))
    18                 else:
    19                     edge[fa].append(x)
    20                     edge[x].append(fa)
    21                     q.append((x, x))
    22 
    23 def getDeep(root):
    24     vis = [0 for _ in range(n + 1)]
    25     d = {}
    26     q = deque()
    27     q.append(root)
    28     vis[root] = 1
    29     d[root] = 0
    30     while q:
    31         u = q.pop()
    32         for x in edge[u]:
    33             if vis[x] == 0:
    34                 vis[x] = 1
    35                 d[x] = d[u] + 1
    36                 q.append(x)
    37     return d
    38 
    39 n = int(input())
    40 precol = [int(_) for _ in input().split()]
    41 preedge = [[] for _ in range(n + 1)]
    42 for _ in range(n - 1):
    43     x, y = [int(_) for _ in input().split()]
    44     preedge[x].append(y)
    45     preedge[y].append(x)
    46 
    47 root = (n + 1) // 2
    48 edge = [[] for _ in range(n + 1)]
    49 col = [0 for _ in range(n + 1)]
    50 for x in range(1, n + 1):
    51     col[x] = precol[x - 1]
    52 buildTree(root)
    53 
    54 d = getDeep(root)
    55 u = max(d.keys(),key=(lambda k:d[k]))
    56 print((max(getDeep(u).values()) + 1 ) // 2)

    由于Python栈空间过小的原因,一直在test15 RE,改了一天,感觉还是C/C++用起来舒心=。=

  • 相关阅读:
    模板与继承之艺术——空基类优化
    模板的多态(静多态)威力
    Linux在vi编辑模式下如何查找
    PHP var_dump() 函数
    PHP empty() 函数
    IOS连接代理后自动关闭
    charles:屏蔽web网页的抓包信息(proxy)
    Python-unittest单元测试框架总结
    fiddler过滤域名:仅显示指定的域名
    Java中System.getProperties()方法获取的系统属性
  • 原文地址:https://www.cnblogs.com/barrier/p/6079728.html
Copyright © 2020-2023  润新知