标签:ace void ble imp def The data- specific tmp
You are given an unweighted tree with nn vertices. Recall that a tree is a connected undirected graph without cycles.
Your task is to choose three distinct vertices a,b,ca,b,c on this tree such that the number of edges which belong to at least one of the simple paths between aa and bb, bb and cc, or aa and cc is the maximum possible. See the notes section for a better understanding.
The simple path is the path that visits each vertex at most once.
The first line contains one integer number nn (3≤n≤2⋅1053≤n≤2⋅105) — the number of vertices in the tree.
Next n−1n−1 lines describe the edges of the tree in form ai,biai,bi (1≤ai1≤ai, bi≤nbi≤n, ai≠biai≠bi). It is guaranteed that given graph is a tree.
In the first line print one integer resres — the maximum number of edges which belong to at least one of the simple paths between aa and bb, bband cc, or aa and cc.
In the second line print three integers a,b,ca,b,c such that 1≤a,b,c≤n1≤a,b,c≤n and a≠,b≠c,a≠ca≠,b≠c,a≠c.
If there are several answers, you can print any.
给出一棵无权树(可理解为边权为 11 ),你需要选取三个点 a,b,ca,b,c ,最大化 a,ba,b 和 b,cb,c 和 a,ca,c 的简单路径的并集的长度。
输出这个最大长度和 a,b,ca,b,c 。
有一个结论:
必定会有一组最优解,使得 a,ba,b 是树直径上的端点。
这个结论我现在暂时不会证明,大家可以去看看其他 dalaodalao 的证明或是自己给出证明 >v<>v< 。
那我们可以套路地去把树直径两端点求出来,这里不推荐用 树形dp ,推荐大家用 两次搜索 求出树直径端点。
确定了 a,ba,b ,接下来我们只要去找到最优的 cc ,就可以最大化答案了。
此时我们注意到:a,ba,b 和 b,cb,c 和 a,ca,c 的简单路径的并集的长度其实就是 dis(a,b)+dis(b,c)+dis(a,c)2dis(a,b)+dis(b,c)+dis(a,c)2 。
此时 dis(a,b)dis(a,b) 已经确定了,当 dis(b,c)+dis(a,c)dis(b,c)+dis(a,c) 的值取到最大,那么整个式子取最大。
把 a,ba,b 到所有点的简单路径距离求出来,去枚举这个最优的 cc 即可,枚举的过程中记得判与 a,ba,b 相同的情况。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=4e5+10; 4 int head[maxn]; int num=-1; 5 int dis[maxn]; 6 int tmp1[maxn],tmp2[maxn]; 7 int pos,ans; 8 struct node 9 { 10 int v,w; 11 int next; 12 }G[maxn]; 13 void add(int u,int v,int w) 14 { 15 G[++num].v=v;G[num].w=w;G[num].next=head[u];head[u]=num; 16 G[++num].v=u;G[num].w=w;G[num].next=head[v];head[v]=num; 17 } 18 void dfs(int u,int fa) 19 { 20 if(dis[u]>ans){ 21 ans=dis[u]; 22 pos=u; 23 } 24 for(int i=head[u];i!=-1;i=G[i].next){ 25 int v=G[i].v; 26 if(v==fa) continue; 27 dis[v]=dis[u]+G[i].w; 28 dfs(v,u); 29 } 30 return; 31 } 32 void init() 33 { 34 memset(head,-1,sizeof(head)); 35 num=-1; 36 } 37 int main() 38 { 39 init(); 40 int n; 41 scanf("%d",&n); 42 for(int i=1;i<n;i++){ 43 int u,v; 44 scanf("%d%d",&u,&v); 45 add(u,v,1); 46 } 47 dfs(1,0); 48 memset(dis,0,sizeof(dis)); 49 int p1=pos; 50 ans=0; 51 dfs(pos,0); 52 int p2=pos; 53 for(int i=1;i<=n;i++) 54 tmp1[i]=dis[i]; 55 memset(dis,0,sizeof(dis)); 56 dfs(pos,0); 57 for(int i=1;i<=n;i++) 58 tmp2[i]=dis[i]; 59 pos=0; 60 for(int i=1;i<=n;i++){ 61 if(tmp1[i]+tmp2[i]>tmp1[pos]+tmp2[pos]&&i!=p1&&i!=p2) 62 pos=i; 63 } 64 ans=(tmp1[p2]+tmp1[pos]+tmp2[pos])/2; 65 printf("%d\n",ans); 66 printf("%d %d %d\n",p1,p2,pos); 67 return 0; 68 }
codeforce F - Three Paths on a Tree
标签:ace void ble imp def The data- specific tmp
原文地址:https://www.cnblogs.com/pangbi/p/12234819.html