• 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 }
  • 相关阅读:
    [原创]mac终端前面的计算机名怎么改??
    iOS获取当前设备方向
    mac电脑Coding显示/隐藏文件
    从tomcat7升级到tomcat8的一个坑
    Tomcat环境开发技巧
    No.2 网络功能
    No.1 持久化
    No.0 项目起步
    读mysqlbinlog二三事
    版本号小常识
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9562766.html
Copyright © 2020-2023  润新知