BZOJ2870 最长道路tree(并查集+LCA)

题意

(n<=50000)

题解

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<cmath>
  5 #include<algorithm>
  6 using namespace std;
  7 const long long N=60000;
  8 long long cnt,head[N];
  9 long long sum[N],dep[N],f[N][25];
 10 long long fa[N];
 11 long long n,a[N],b[N],book[N],ans;
 12 struct edge{
 13     long long to,nxt;
 14 }e[N*2];
 15 struct node{
 16     long long w,id;
 17 }c[N];
 18 void add(long long u,long long v){
 19     cnt++;
 20     e[cnt].nxt=head[u];
 21     e[cnt].to=v;
 22     head[u]=cnt;
 23 }
 24 void dfs(long long u,long long ff,long long deep,long long w){
 25     sum[u]=w;
 26     f[u][0]=ff;
 27     dep[u]=deep;
 28     for(long long i=head[u];i;i=e[i].nxt){
 29         long long v=e[i].to;
 30         if(v==ff)continue;
 31         dfs(v,u,deep+1,w+1);
 32     }
 33 }
 34 bool cmp(node a,node b){
 35     return a.w>b.w;
 36 }
 37 long long find(long long x){
 38     if(fa[x]==x)return x;
 39     else return fa[x]=find(fa[x]);
 40 }
 41 long long getlca(long long x,long long y){
 42     if(dep[x]<dep[y])swap(x,y);
 43     for(long long i=20;i>=0;i--){
 44         if(dep[f[x][i]]>=dep[y]){
 45             x=f[x][i];
 46         }
 47     } 
 48     if(x==y)return x;
 49     for(long long i=20;i>=0;i--){
 50         if(f[x][i]!=f[y][i]){
 51             x=f[x][i];y=f[y][i];
 52         }
 53     }
 54     return f[x][0];
 55 }
 56 long long getline(long long x,long long y){
 57     long long LCA=getlca(x,y);
 58     return sum[x]+sum[y]-sum[LCA]*2+1; 
 59 }
 60 void merge(long long x,long long y){
 61     long long tmp=0,cx,cy,len;
 62     len=getline(a[x],b[x]);if(len>tmp){cx=a[x];cy=b[x];tmp=len;}
 63     len=getline(a[y],b[y]);if(len>tmp){cx=a[y];cy=b[y];tmp=len;}
 64     len=getline(a[x],a[y]);if(len>tmp){cx=a[x];cy=a[y];tmp=len;}
 65     len=getline(b[x],b[y]);if(len>tmp){cx=b[x];cy=b[y];tmp=len;}
 66     len=getline(a[x],b[y]);if(len>tmp){cx=a[x];cy=b[y];tmp=len;}
 67     len=getline(a[y],b[x]);if(len>tmp){cx=a[y];cy=b[x];tmp=len;}
 68     fa[y]=x;
 69     a[x]=cx;
 70     b[x]=cy;
 71 }
 72 int main(){
 73     scanf("%lld",&n);
 74     for(long long i=1;i<=n;i++){
 75         scanf("%lld",&c[i].w);
 76         c[i].id=i;
 77     }
 78     for(long long i=1;i<n;i++){
 79         long long u;long long v;
 80         scanf("%lld%lld",&u,&v);
 81         add(u,v);
 82         add(v,u);
 83     }
 84     for(long long i=1;i<=n;i++){
 85         a[i]=b[i]=i;fa[i]=i;
 86     }
 87     dfs(1,0,1,0);
 88     for(long long i=1;i<=20;i++){
 89         for(long long j=1;j<=n;j++){
 90             f[j][i]=f[f[j][i-1]][i-1];
 91         }
 92     }
 93     sort(c+1,c+1+n,cmp);
 94     for(long long i=1;i<=n;i++){
 95         long long u=c[i].id;
 96         book[u]=1;
 97         for(long long j=head[u];j;j=e[j].nxt){
 98             long long v=e[j].to;
 99             if(book[v]==0)continue;
100             merge(find(u),find(v));
101         }
102         ans=max(ans,c[i].w*getline(a[u],b[u])); 
103     }
104     printf("%lld",ans);
105     return 0;
106 }
原文地址:https://www.cnblogs.com/Xu-daxia/p/9562766.html