• POJ 3567 Cactus Reloaded(仙人掌直径)


    题意

    裸的仙人掌直径。

    题解

    先考虑基环树的直径:先算出每颗“树”的直径,再在环上跑DP

    再考虑仙人掌的直径:把每个基环树缩成一条边,边长为基环树深度。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 const int N=50010;
     8 const int M=10010;
     9 int cnt,head[N];
    10 int c[N*2],dp[N],q[N*2],ans;
    11 int dfn[N],low[N],tot,fa[N];
    12 int n,m;
    13 struct edge{
    14     int to,nxt;
    15 }e[M*20];
    16 void add(int u,int v){
    17     cnt++;
    18     e[cnt].nxt=head[u];
    19     e[cnt].to=v;
    20     head[u]=cnt;
    21 }
    22 void getdp(int x,int y){
    23     int l,r,i,m,p;
    24     for(m=0;y!=x;y=fa[y])c[++m]=dp[y];
    25     for(c[++m]=dp[x],i=1;i<m;i++)c[i+m]=c[i];
    26     l=r=q[1]=1;p=m/2;
    27     for(i=2;i<=m+p;i++){
    28         while(l<=r&&i-q[l]>p)l++;
    29         ans=max(ans,c[i]+c[q[l]]+i-q[l]);
    30         while(l<=r&&c[i]>=c[q[r]]+i-q[r])r--;
    31         q[++r]=i;
    32     }
    33     for(int i=1;i<m;i++)dp[x]=max(dp[x],c[i]+min(i,m-i));
    34 }
    35 void Tarjan(int u){
    36     dfn[u]=low[u]=++tot;
    37     for(int i=head[u];i;i=e[i].nxt){
    38         int v=e[i].to;
    39         if(fa[u]==v)continue;
    40         if(dfn[v]==0){
    41             fa[v]=u;
    42             Tarjan(v);
    43             low[u]=min(low[v],low[u]);
    44             if(dfn[u]<low[v]){
    45                 ans=max(ans,dp[v]+dp[u]+1);
    46                 dp[u]=max(dp[u],dp[v]+1);
    47             }
    48         }else low[u]=min(low[u],dfn[v]);
    49     }
    50     for(int i=head[u];i;i=e[i].nxt){
    51         int v=e[i].to;
    52         if(fa[v]!=u&&dfn[u]<dfn[v])getdp(u,v);
    53     }
    54 }
    55 int main(){
    56     scanf("%d%d",&n,&m);
    57     for(int i=1,a,x;i<=m;i++){
    58         scanf("%d%d",&a,&x);
    59         for(int j=1,y;j<a;j++){
    60             scanf("%d",&y);
    61             add(x,y);
    62             add(y,x);
    63             x=y;
    64         }
    65     }
    66     Tarjan(1);
    67     printf("%d",ans);
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    数组
    JavaScript语法
    Math.random()
    第二第三周暑期集训总结
    第一周
    ACM课程学习总结
    专题四---总结
    专题四--1004
    专题四--1005
    专题四--1006
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9381086.html
Copyright © 2020-2023  润新知