[CF911F]Tree Destruction

Posted slrslr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF911F]Tree Destruction相关的知识,希望对你有一定的参考价值。

题意翻译

给你一棵树,每次挑选这棵树的两个叶子,加上他们之间的边数(距离),然后将其中一个点去掉,问你边数(距离)之和最大可以是多少.

 

首先我们知道,到一个点距离最远的点是直径的端点。考虑贪心,如果我要最大化一个不在选定直径上的点的贡献,一定是将它和某个直径的端点连在一起算贡献。也就是说在这个点消失前直径一直存在,所以我们先把直径外的点全部删除并选择一个较远的直径端点计算贡献,然后再删除直径上的点即可。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<cstring>
 5 #define M 200010
 6 using namespace std;
 7 int read()
 8 {
 9     char ch=getchar();int x=0;
10     while(ch>9||ch<0) ch=getchar();
11     while(ch>=0&&ch<=9) x=x*10+ch-0,ch=getchar();
12     return x;
13 }
14 int n,m,num,L,R,cnt;
15 int head[M],id[M],deep[M],f[M],fa[M],in[M];
16 int res1[M],res2[M],res3[M];
17 bool vis[M];
18 long long ans;
19 queue<int>Q;
20 struct point{int to,next;}e[M<<1];
21 void add(int from,int to)
22 {
23     e[++num].next=head[from];
24     e[num].to=to;
25     head[from]=num;
26 }
27 void dfs(int x,int fa)
28 {
29     for(int i=head[x];i;i=e[i].next)
30     {
31         int to=e[i].to;
32         if(to==fa) continue;
33         deep[to]=deep[x]+1;
34         dfs(to,x);
35     }
36 }
37 void mark(int x,int tar)
38 {
39     while(1)
40     {
41         vis[x]=true;int nxt=0;
42         if(x==tar) return;
43         for(int i=head[x];i;i=e[i].next)
44         {
45             int to=e[i].to;
46             if(deep[to]==deep[x]-1)
47             {
48                 nxt=to;
49                 break;
50             }
51         }
52         fa[x]=nxt;x=nxt;
53     }
54 }
55 int main()
56 {
57     n=read();
58     for(int a,b,i=1;i<n;i++)
59     {
60         a=read();b=read();
61         add(a,b); add(b,a);
62         in[a]++,in[b]++;
63     }
64     deep[1]=1;
65     dfs(1,0);
66     for(int i=1;i<=n;i++) if(deep[i]>deep[L]) L=i;
67     deep[L]=1; dfs(L,0);
68     for(int i=1;i<=n;i++) f[i]=deep[i]-1,id[i]=L;
69     for(int i=1;i<=n;i++) if(deep[i]>deep[R]) R=i;
70     deep[R]=1; dfs(R,0);
71     for(int i=1;i<=n;i++) if(deep[i]-1>f[i]) f[i]=deep[i]-1,id[i]=R;
72     deep[L]=1; dfs(L,0); mark(R,L);
73     for(int i=1;i<=n;i++) if(in[i]==1&&!vis[i]) Q.push(i);
74     while(!Q.empty())
75     {
76         int x=Q.front();Q.pop();
77         res1[++cnt]=x;res2[cnt]=id[x];res3[cnt]=x;
78         ans+=f[x];
79         for(int i=head[x];i;i=e[i].next)
80         {
81             int to=e[i].to;
82             in[to]--;
83             if(!vis[to]&&in[to]==1) Q.push(to);
84         }
85     }
86     for(int i=R;i!=L;i=fa[i])
87     {
88         res1[++cnt]=i;res2[cnt]=L;res3[cnt]=i;
89         ans+=deep[i]-deep[L];
90     }
91     printf("%lld
",ans);
92     for(int i=1;i<=cnt;i++) printf("%d %d %d
",res1[i],res2[i],res3[i]);
93     return 0;
94 }

 

以上是关于[CF911F]Tree Destruction的主要内容,如果未能解决你的问题,请参考以下文章

「CF911F」Tree Destruction

[CF911F]Tree Destruction

cf963b Destruction of a Tree

CF963B Destruction of a Tree

CF.911F.Tree Destruction(构造 贪心)

CF1474C - Array Destruction