HDU 4275 Color the Tree does not repeatedly dye the Tree to find the center of the Tree + hash

Source: Internet
Author: User

Given a tree composed of n (n <= 50000) points, it is colored by m (m <= 100000) and the question is not repeated (by rotation) the number of dyeing methods.
Question: This question is completely understandable by People's code...
First, find the center of the tree (not the center of gravity). The center is defined as the midpoint of the tree's diameter. If the number of nodes on the diameter is an even number, create a new node in the center.
Then obtain the corresponding hash value for each subtree from the central dfs (hash method: hash [I] = A * (hash [j1] * B) ^ hash [j2] * B ..... ^ hash [jn] * C % D; (sequential execution )),
After sorting, the sub-trees with homogeneous structures must be arranged in adjacent locations. In this way, the x1 + x2 + ...... + Xans [I] = cnt get the number of methods used to dye the child tree of the current shape, and then get the final answer.
The correctness of the dot-point dfs is described below:
Define attribute x: when a father node whose root node fa is u, any hash [son] is not equal to hash [fa] (hash value of the upper subtree ).
If the midpoint dfs is obtained, the nature of all dfs nodes is satisfied. longest [I] is defined as the maximum distance from the root node to the leaf node with I as the diameter of the tree.
Because longest [fa] (top subtree & fa! = Center)> = l/2, longest [I] <l/2, so the x property is satisfied. In this way, the correctness is guaranteed and the homogeneous subtree is not omitted.

Sure original, reprinted please indicate the source.
[Cpp]
# Include <iostream>
# Include <cstdio>
# Include <memory. h>
# Include <algorithm>
Using namespace std;
Const int maxn = 50005;
Const int maxm = 100002;
Const int leaf = 9778972;
Const int yin = 10003;
Const int yyyy = 131237;
Const int mod = 1000000007;
Struct node
{
Int v;
Int next;
} Edge [maxn <1];
Struct H
{
_ Int64 hash, ans;
Bool operator <(const H & other) const
{
Return hash <other. hash;
}
} Val [maxn];
Int head [maxn], down [maxn], longest [maxn];
_ Int64 ans [maxn], hash [maxn], A [maxm];
Int m, n, bj, idx, root, path;
 
Void prepare ()
{
A [0] = A [1] = 1;
For (int I = 2; I <maxm; I ++)
{
A [I] = A [I-1] * I;
A [I] % = mod;
}
Return;
}
 
Void init ()
{
Memset (head,-1, sizeof (head ));
Memset (down,-1, sizeof (down ));
Idx = path = 0;
Bj = root =-1;
Return;
}
 
Void addedge (int u, int v)
{
Edge [idx]. v = v;
Edge [idx]. next = head [u];
Head [u] = idx ++;
 
Edge [idx]. v = u;
Edge [idx]. next = head [v];
Head [v] = idx ++;
Return;
}
 
Void read ()
{
Int u, v;
For (int I = 1; I <n; I ++)
{
Scanf ("% d", & u, & v );
Addedge (u, v );
}
Return;
}
 
_ Int64 powmi (_ int64 a, int x)
{
_ Int64 res = 1;
While (x)
{
If (x & 1)
{
Res * =;
Res % = mod;
}
A * =;
A % = mod;
X> = 1;
}
Return res;
}
 
_ Int64 C (_ int64 n, int m)
{
If (n = 1LL * m) return 1LL;
_ Int64 res = 1;
For (int I = 1; I <= m; I ++)
{
Res * = 1LL * (n-I + 1 );
Res % = mod;
}
Res * = powmi (A [m], mod-2 );
Return res % mod;
}
 
Void DFS (int st, int pre)
{
Int l = 0, ll = 0;
For (int I = head [st]; I! =-1; I = edge [I]. next)
{
If (edge [I]. v = pre) continue;
DFS (edge [I]. v, st );
If (longest [edge [I]. v]> l)
{
Ll = l;
L = longest [edge [I]. v];
Down [st] = I;
}
Else if (longest [edge [I]. v]> ll) ll = longest [edge [I]. v];
}
If (l + ll + 1> path)
{
Path = l + ll + 1;
Root = st;
}
Longest [st] = l + 1;
Return;
}
 
Void make ()
{
DFS (1, 0 );
If (path & 1)
{
While (longest [root] * 2-1> path)
{
Root = edge [down [root]. v;
}
Ans [root] = 1LL * m;
}
Else
{
While (longest [root] * 2-2> path)
{
Root = edge [down [root]. v;
}
Addedge (root, ++ n );
Addedge (n, edge [down [root]. v );
Bj = down [root];
Root = n;
Ans [root] = 1LL;
}
Return;
}
 
Void dfs (int st, int pre)
{
Int num = 0;
For (int I = head [st]; I! =-1; I = edge [I]. next)
{
If (edge [I]. v = pre) continue;
If (bj! =-1 & (I = bj | I = (bj ^ 1) continue;
Num ++;
Ans [edge [I]. v] = 1LL * m;
Dfs (edge [I]. v, st );
}
If (num = 0)
{
Hash [st] = leaf;
Return;
}
Int c = 0;
For (int I = head [st]; I! =-1; I = edge [I]. next)
{
If (edge [I]. v = pre) continue;
If (bj! =-1 & (I = bj | I = (bj ^ 1) continue;
Val [c]. hash = hash [edge [I]. v];
Val [c ++]. ans = ans [edge [I]. v];
}
Sort (val, val + num );
Hash [st] = leaf;
For (int I = 0; I <num ;)
{
Int j = I;
For (; j <num & val [I]. hash = val [j]. hash; j ++)
{
Hash [st] * = yin;
Hash [st] ^ = val [j]. hash;
Hash [st] % = mod;
}
Hash [st] = hash [st] * yy % mod;
Ans [st] * = C (val [I]. ans + j-I-1, j-I );
Ans [st] % = mod;
I = j;
}
Return;
}
 
Int main ()
{
Prepare ();
While (~ Scanf ("% d", & n, & m ))
{
Init ();
Read ();
Make ();
Dfs (root, 0 );
Printf ("% I64d \ n", ans [root]);
}
Return 0;
}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.