USACO 07 CHN 3

Original links: http://ace.delos.com/TESTDATA/CHN07.treasure.htm

 

To tackle this problem most effectively, we first establish that the road network described in the problem is a cycle with trees 'coming off' it. So we can root all the trees by the vertex they have on the cycle and denote nodes by 'parent' and children'.

We essentially want to assign an 'id' to the graph surrounding each of the vertices, which is a collection of several subtrees (its children) and a graph that contains the cycle.

There are two ways of doing this, either by computing hash values for each subgraph or by computing 'ids' as we proceed and only hash cyclic shifts of the cycle. The first method is faster in practice and just accurate, but the second is slightly easier to code due to usage of C++ STL.

Since a tree is a collection of its subtrees, we can assign 'id's to all the subtrees rooted at each vertex by proceeding at the outermost layer and proceed inwards.

Then we have to distinguish between all the cyclic shifts (with reflections) of the cycles (which is how we could 'orient' the cycle with respect to the tree the treasure is buried in). This can be accomplished by the standard Rabin-Karp string hash, done once clockwise and once counter clockwise.

Then for each distinct tree, we can just count the trees that have distinct ids by going down recursively, and when we're at a node, only count its children that have distinct ids (so if two of its children have the same subtree, only count one of them). This is correct since the 'root' is now a special node (an orientation of the cycle).

This runs in O(N) time if hashing is used and O(NlogN) if set/map is used. The test data were generated as follows:

 

But the description of the problem on http://poj.grids.cn/practice/3380/ is incorrect and misguided!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值