标签:+= 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 }
标签:+= etc main int tree name tin des 消失
原文地址:https://www.cnblogs.com/Slrslr/p/9678163.html