图论题【1】

题意


input

5
1 2
2 3
3 4
4 5

output

1

限制与约定

(3≤n≤200000)

题解

如果只放一个点,很显然就是放在直径的中点上面,这样一定是最优的,

[Ans=(len(直径)+1)/2$$而现在题目要求取两个点, 我们想象在两点路径的中点及其子树到两点的路径均相等, 而在中点右边(没有中点一样)到右边选的点的距离一定小于到左边选的点的距离。 当然,左边同理。 即现在题目要求断开一条边,然后使得两个部分的最长直径最短。 而断开这条边的位置,一定是在原来那棵树的直径上面。 于是呢,就把直径抽出来,把直径上每个点及其子树(子树不包括直径上其他点) 都记录一个最长直径,以及以这个点开始能走的最长距离与次长距离。 求出断开每一条边的左半部分的直径分别是多少, 在处理一遍右边的,组合一下就好了 ## code ```cpp #include <bits/stdc++.h> #define re register int #define inf 1e9 using namespace std; inline void read(int &x){ x=0;char ch=getchar(); for(;!isdigit(ch);ch=getchar()); for(; isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48); } inline void print(int x){if(x>9)print(x/10);putchar((x%10)+48);} const int N=200010; int n,q,f[N],to[N<<1],nx[N<<1],h[N],d[N],c,v[N],l[N][4],g[N],dis[N],ans=N; inline void add(int u,int v){to[++c]=v,nx[c]=h[u],h[u]=c;} inline void dfs(int x,int fa){ f[x]=fa,d[x]=d[fa]+1; for(re i=h[x];i;i=nx[i]) if(to[i]!=fa)dfs(to[i],x); } inline void get(int x,int fa){ l[x][1]=l[x][2]=l[x][3]=0; for(re i=h[x];i;i=nx[i]) if(to[i]!=fa&&!v[to[i]]){ get(to[i],x); re tmp=l[to[i]][1]+1; if(tmp>=l[x][1]) l[x][2]=l[x][1],l[x][1]=tmp; else if(tmp>l[x][2])l[x][2]=tmp; l[x][3]=max(l[to[i]][3],(l[x][1]+l[x][2])); } } signed main(){ freopen("ob.in","r",stdin); freopen("ob.out","w",stdout); read(n);int x,y,l1=0,l2=0; for(re i=1;i<n;++i) read(x),read(y),add(x,y),add(y,x); dfs(1,0); for(re i=1;i<=n;++i) if(d[i]>d[l1]) l1=i; dfs(l1,0); for(re i=1;i<=n;++i) if(d[i]>d[l2]) l2=i; for(re i=l2;i;i=f[i]) v[i]=1; for(re i=l2;i;i=f[i]) get(i,0); for(re i=l2;i;i=f[i]){ g[f[i]]=i; re tmp=l[g[i]][1]+1; if(g[i]==0) tmp=0; if(tmp>=l[i][1]) l[i][2]=l[i][1],l[i][1]=tmp; else if(tmp>l[i][2])l[i][2]=tmp; dis[i]=l[i][3]=max(l[g[i]][3],(l[i][1]+l[i][2])); } for(re i=l2;i;i=f[i]) get(i,0); for(re i=l1;i;i=g[i]){ re tmp=l[f[i]][1]+1; if(f[i]==0) tmp=0; if(tmp>=l[i][1]) l[i][2]=l[i][1],l[i][1]=tmp; else if(tmp>l[i][2])l[i][2]=tmp; l[i][3]=max(l[f[i]][3],(l[i][1]+l[i][2])); ans=min(ans,max(l[i][3],dis[g[i]])); } print((ans+1)>>1); return 0; } ```]

原文地址:https://www.cnblogs.com/Sparks-Pion/p/9691346.html