Codeforces 391E2 ("Codeforces Rockethon 2014" E2)

Source: Internet
Author: User

/*
Test instructions: There are three trees, each tree has NI nodes, add two sides to connect the three trees together, merge into a tree, so that the shortest path between any two points in the tree
and the largest.
Analysis:
Three trees to merge into a tree, then the first tree must choose a point, assuming X, the second tree must choose two points, assuming that the Y1, Y2, the third tree must choose a point, assuming that Z
The sum of the paths of all nodes to X in the first tree is: tot1
The sum of the paths of all nodes to y1,y2 in the second tree is: Tot2, tot3
The sum of the paths of all nodes to Z in the third tree is: TOT4;
There are four types of cases:
1, the distance between nodes within each tree is constant, you can find the sum of the paths of one point in the tree to all remaining points, and divide all such points and add them by 2.
2, the first tree and the second tree the distance between all nodes of the two trees, assuming that the first tree chooses node X, the second tree chooses the left node Y1,
Then the distance between any two points, a, b, of the two trees can be expressed as: D (A, c) = d (A, X) + 1 + d (b, Y1),
Where a is an arbitrary node of the first tree, and B is any node of the second tree,
Fixed point A, transform BJ, because the second tree has a N2 node, then the total path for this case is: (D (A, X) + 1) * n2 + sum (d (BJ, Y1), j = 1, 2, ..., n2);
Then transform the AI, then the resulting path is: Sum ((d (AI, X) + 1) * n2 + sum (d (BJ, Y1), j = 1, 2, ..., n2), i = 1, 2, ..., N1);
The final result is: sum (d (AI, X), i = 1, 2, ..., N1) * n2 + n2 * n1 + sum (d (BI, Y1), j = 1, 2, ..., n2) * N1;
i.e. Tot1 * n2 + n2 * n1 + tot2 * N1;
3, the second tree and the third tree the distance between all nodes of the two trees, similar to the case 2, the resulting result is: TOT3 * n3 + n2 * n3 + tot4 * n2;

4, the distance between all nodes of the first tree and the third tree: Each path can be represented as: D (A, c) = d (A, X) + 1 + d (Y1, Y2) + 1 + d (Z, c);
The end result is: TOT1 * n3 + TOT4 * n1 + n1 * N2 * d (Y1, Y2) + 2 * N1 * n3;

In summary, the sum of the distances between the nodes in the tree after the merge is:
sum = (n2 + n3) * TOT1 + (n1 + n2) * TOT4 + n1 * n2 + n2 * n3 + 2 * N1 * n3 + n1 * Tot2
+ N3 * TOT3 + n1 * N3 * d (Y1, Y2) + three-tree internal path;
To make the sum maximum, the TOT1 and TOT4 must be the largest, the upper middle part is constant, then left = N1 * Tot2 + n3 * TOT3 + n1 * N3 * d (Y1, Y2) must reach maximum
When the tot2 reaches the maximum, that is, when Y1 is determined, the enumeration Y2 allows the left part to reach the maximum.
This process enumerates the locations of the three trees.
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace Std;
typedef long Long LL;
const int MAXN = 100000 + 10;
struct Edge
{
int y, Next;
};
struct Tree
{
LL N, Head[maxn], NODECNT[MAXN], edgecnt, DIS[MAXN], POS, Maxtot;
LL CURSUM[MAXN], TOT[MAXN], pathcnt;
Edge EDGE[MAXN << 1];
void Addedge (int x, int y)
{
Edge[edgecnt].y = y;
Edge[edgecnt].next = Head[x];
HEAD[X] = edgecnt++;
}

void build (int n)
{
Memset (Head,-1, sizeof (head));
This->n = n;
int x, y;
for (int i = 1; i < n; i++)
{
scanf ("%d%d", &x, &y);
Addedge (x, y);
Addedge (y, x);
}
}

/* Get the node in Son's tree Nodecnt[son], including the parent node, and get the sum of all the child nodes in the tree of Son and the path to son, saved in Cursum[son]
where Cursum[son] = SUM (Cursum[yi] + nodecnt[yi], i = 1, 2, ...), which is the shortest path value of all subtrees plus the sum of all the points of the subtree
*/
void Dfs0 (int son, int fa)
{
Nodecnt[son] = 1;
Cursum[son] = 0;
int y;
for (int i = Head[son]; I! =-1; i = edge[i].next)
{
y = edge[i].y;
if (y = = FA)
{
Continue
}
Dfs0 (y, son);
Backtracking, the value of the child node Y has been obtained.
Nodecnt[son] + = Nodecnt[y];
Cursum[son] + = Cursum[y] + nodecnt[y];
}
}

Get Tot[son], i.e. the sum of all points to son's path
void dfs1 (int son, int fa, LL faleft)
{
The sum of the paths of the current son's subtree, plus the sum of the other remainder to the path of son.
Tot[son] = Cursum[son] + faleft;
int y;
for (int i = Head[son]; I! =-1; i = edge[i].next)
{
y = edge[i].y;
if (y = = FA)
{
Continue
}
/*y nodes In addition to the subtree, there are three parts of the value that should be added:
Son this tree should have added value, that is, the whole tree minus the rest of son tree to son's path and Faleft,
Son, this tree, except for y, this subtrees tree. All nodes to the path value of son are left outside the path and:
Son the shortest path of the tree and-y the shortest path of the tree and-the node of the son of the tree, i.e. Cursum[son]-cursum[y]-nodecnt[y];
Y Sub-tree node: n-nodecnt[y]
*/
DFS1 (Y, son, Faleft + Cursum[son]-cursum[y]-nodecnt[y] + n-nodecnt[y]);
}
}

Depth traversal, get the hierarchy of each node, that is, the shortest path to the root node, note that the root node level is 0.
void dfs2 (int son, int fa)
{
Dis[son] = Dis[fa] + 1;
int y;
for (int i = Head[son]; I! =-1; i = edge[i].next)
{
y = edge[i].y;
if (y = = FA)
{
Continue
}
DFS2 (y, son);
}
}

void Solve ()
{
DFS0 (1, 0);
DFS1 (1, 0, 0);
Find the maximum single-point shortest path and, at the same time, accumulate, which is twice times the sum of the paths within the tree
for (int i = 1; I <= n; i++)
{
Pathcnt + = Tot[i];
if (Tot[i] > Maxtot)
{
Maxtot = Tot[i];
pos = i;
}
}
Dis[0] =-1;
DFS2 (POS, 0);
}
};

Tree T[3];

LL Getans (const tree &AMP;T1, const tree &t2, const tree &AMP;T3)
{
The first part of the change
LL tmp = (T2.N + T3.N) * T1.maxtot + (T1.N + T2.N) * T3.maxtot + T1.N * T2.N + T2.N * T3.N + 2 * T1.N * T3.N
+ (t1.pathcnt + t2.pathcnt + t3.pathcnt)/2;
LL ans, Maxans = 0;

Fixed Y1,t2.maxtot equivalent to Tot2
TMP + = T1.N * T2.maxtot;

Enumeration Y2
for (int i = 1; I <= T2.N; i++)
{
Assuming the current t2.tot[i] is tot3,t2.dis[i] distance from Y2 to Y1, Y1 as a single origin
Ans = (LL) tmp + T3.N * T2.tot[i] + T1.N * T3.N * t2.dis[i];
Maxans = max (ans, maxans);
}
return Maxans;
}

int main ()
{
int n[3], I, J;
LL ans = 0;
Freopen ("In.txt", "R", stdin);
scanf ("%d%d%d", &n[0], &n[1], &n[2]);
for (i = 0; i < 3; i++)
{
T[i].build (N[i]);
T[i].solve ();
}

Enumerate the locations of the three trees
for (i = 0; i < 3; i++)
{
for (j = 0; J < 3; J + +)
{
if (i = = j)
{
Continue
}
ans = max (ans, Getans (T[i], t[j], T[3-i-j]));
}
}
printf ("%i64d\n", ans);
return 0;
}

Reference Blog: http://www.cnblogs.com/Delostik/p/3553114.html

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Codeforces 391E2 ("Codeforces Rockethon 2014" E2)

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.