码迷,mamicode.com
首页 > 其他好文 > 详细

[CF911F]Tree Destruction

时间:2018-09-19 23:39:04      阅读:379      评论:0      收藏:0      [点我收藏+]

标签:+=   etc   main   int   tree   name   tin   des   消失   

题意翻译

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

 

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

代码:

 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\n",ans);
92     for(int i=1;i<=cnt;i++) printf("%d %d %d\n",res1[i],res2[i],res3[i]);
93     return 0;
94 }

 

[CF911F]Tree Destruction

标签:+=   etc   main   int   tree   name   tin   des   消失   

原文地址:https://www.cnblogs.com/Slrslr/p/9678163.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!