P3174 [HAOI2009] caterpillar problem solution

Park synchronization blog

Original title link

Briefly meaning of the questions:

Given a tree, find the longest "fob" length.

Lanyards defined: on one strand spanning all the nodes connected thereto configuration. (Non-strict definitions) (the original title is "Caterpillar", I thought lanyards more images)

This problem has a variety of approaches, here are ideas, as well as one of the code of practice.

A algorithm

Notes that, in fact, we only need to select the "longest chain", then both sides can lanyards in the longest chain.

That is, first find the tree diameter two endpoints, and the endpoints traverse over the diameter, the edges thereof are added directly connected spanning tree.

The answer to the last statistics.

time complexity: THE ( n ) O (n) .

Expectations rating: 100 p t s 100pts .

Algorithms two

Consider the tree dp \text{dp} , with f i f_i Expressed i i is the maximum root length lanyards, s in b i sub_i recording i i number of his son, then:

f in = max ( f v , f v + s u b u 1 ) ( v son ( u ) ) f_u = \max(f_v , f_v + sub_u - 1) (v \in \operatorname{son} (u))

Obviously, the answer to either the direct successor son node, or to both sides of a fight.

time complexity: O ( n ) O (n) .

Expectations rating: 100 p t s 100pts .

Algorithm for Three

Gives one of the most ingenious algorithm.

Hypothesis i i of the number of points is a i a_i , The length of a s s lanyards answer should be:

( i list a i ) ( s 1 ) + 1 \bigg ( \sum_{i \in \operatorname{list}} a_i \bigg ) -(s-1) + 1

i list i \in \operatorname{list} represents i i belong to the current chain, s 1 s-1 i.e., the side removed to give double counting the number of edges, and + 1 +1 obtained points. Simplification namely:

= ( i list a i ) s + 2 = \bigg ( \sum_{i \in \operatorname{list} } a_i \bigg ) - s + 2

You find this thing a little ugly, so for a moment:

= i list ( a i 1 ) + 2 =\sum_{i \in \operatorname{list} } (a_i - 1) + 2

Clearly, the s s reduced inside each node, each dotted 1 1 Ge.

Then we can solve the following steps:

  1. Build a statistical chart and degrees 1 -1 .

  2. Diameter at both ends is obtained.

  3. All of the nodes on the statistical diameter, then + 2 +2 is the answer.

time complexity: O ( n ) O (n) .

Actual score: 100 p t s 100pts .

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

const int N=3e5+1;

inline int read(){char ch=getchar();int f=1; while(!isdigit(ch)) {if(ch=='-') f=-f; ch=getchar();}
	   int x=0;while(isdigit(ch)) x=x*10+ch-'0',ch=getchar(); return x*f;}

int n,m,du[N],dis[N];
int num,mx;
vector<int> G[N];

inline void dfs(int dep,int fa,int dis) {
//fa 是 dep 的父亲 , dep 是正在搜索的节点,dis 是它与开始搜索节点的距离,dis 统计度和
	if(dis>mx) mx=dis,num=dep; //度和打擂
	for(int i=0;i<G[dep].size();i++)
		if(G[dep][i]!=fa) dfs(G[dep][i],dep,dis+du[dep]); //往下搜索
}

int main(){
	n=read(),m=read();
	memset(du,-1,sizeof(du)); //初始化为 -1, 即减掉 1
	while(m--) {
		int x=read(),y=read();
		G[x].push_back(y);
		G[y].push_back(x);
		du[x]++; du[y]++; //统计度
	} dfs(1,0,du[1]); mx=0;
	dfs(num,0,du[num]); //两次 dfs 寻找直径
	printf("%d\n",mx+2); // +2 就是答案
	return 0;
}

Published 53 original articles · won praise 74 · views 7001

Guess you like

Origin blog.csdn.net/bifanwen/article/details/105343426