51nod 1737 matching problem solution

Topic portal

The main idea of ​​the topic: Given a tree, the contribution of the pairing of two points is the distance between the two points, and find the maximum contribution sum.

answer

For some reason, come to the solution of this problem, if you come from a hyperlink, you probably know the reason qwq.

The idea is greedy. For each edge, the number of contributions is the size of the smaller subtree of the two connected subtrees. Obviously this is the maximum number of contributions. What needs to be proved is that there is always a solution that makes The number of contributions of each edge is the largest. A scheme is given below:

First find the center of gravity of the tree as the root, and then color each point. The colors of the two points are the same if and only if the two points belong to the subtree of the same son of the root node. In particular, the color of the root node is different from other points. .

Next, pair these points and make sure that the colors of the paired points are different. Put the points of the same color together, for i ∈ [1, n 2] i\in[1,\dfrac n 2]i[1,2n] Points, and compare it with thei + n 2 i+\dfrac n 2i+2nMatching points, so that you can ensure that the colors of the matched points are different, because the center of gravity of the tree has a property: the size of each subtree does not exceed n 2 \dfrac n 22n, That is, the number of points for each color does not exceed n 2 \dfrac n 22n, Then iii Individual point sumi + n 2 i + \ dfrac n 2i+2n The color of each dot must be different.

For example, for a tree like this:
Insert picture description here
2, 3, 4 2,3,42,3,The colors of 4 are the same, and the other points are different from each other.

Putting the same color together is 1, 5, 6, 2, 3, 4 1,5,6,2,3,41,5,6,2,3,4n 2 = 3 \ dfrac n 2 = 32n=3 , Immediatelyiii number andi + 3 i+3i+3 pairs of numbers,(1, 2), (5, 3), (6, 4) (1,2),(5,3),(6,4)(1,2),(5,3),(6,4 ) , this is the optimal matching plan, you can fill in some side rights to play with it.

code show as below:

#include <cstdio>
#include <algorithm>
using namespace std;
#define maxn 100010

int n;
struct edge{
    
    int y,z,next;}e[maxn<<1];
int first[maxn],len=0;
void buildroad(int x,int y,int z){
    
    e[++len]=(edge){
    
    y,z,first[x]};first[x]=len;}
int size[maxn];
long long ans=0;
void dfs(int x,int fa){
    
    
	size[x]=1;
	for(int i=first[x],y;i;i=e[i].next)
	if((y=e[i].y)!=fa)dfs(y,x),ans+=1ll*e[i].z*min(size[y],n-size[y]),size[x]+=size[y];
}

int main()
{
    
    
	scanf("%d",&n);for(int i=1,x,y,z;i<n;i++)
	scanf("%d %d %d",&x,&y,&z),buildroad(x,y,z),buildroad(y,x,z);
	dfs(1,0);printf("%lld",ans);
}

Guess you like

Origin blog.csdn.net/a_forever_dream/article/details/108336509