码迷,mamicode.com
首页 > 其他好文 > 详细

P4244 [SHOI2008]仙人掌图 II

时间:2018-12-31 00:01:30      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:read   ext   name   show   next   string   algo   https   void   

P4244 [SHOI2008]仙人掌图 II

仙人掌求直径,和树一样最大+次大
处理环时,算一下环内两点距离+子树最大和,根节点此时的其他子树已确定的最大子树 用 环内一点距离+点最大子树更新

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const LL maxn=1e7;
inline LL Read(){
    LL x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-') f=-1; c=getchar();
    }
    while(c>='0'&&c<='9')
        x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x*f;
}
struct node{
    LL to,next;
}dis[maxn];
LL n,m,num,ans,tot;
LL dp[maxn],dep[maxn],low[maxn],dfn[maxn],a[maxn],head[maxn],fa[maxn],q[maxn];
inline void Add(LL u,LL v){
    dis[++num]=(node){v,head[u]},head[u]=num;
}
inline void Dp(LL u,LL v){
    LL len=dep[v]-dep[u]+1,j=len;
    for(int i=v;i!=u;i=fa[i])
        a[j--]=dp[i]; a[j]=dp[u];
    for(LL i=1;i<=len;++i)
        a[i+len]=a[i];
    LL hea=1,tail=1; 
    q[1]=1;
    for(LL i=2;i<=len*2;++i){
        while(hea<=tail&&i-q[hea]>len/2) 
            hea++;
        ans=max(ans,a[i]+i+a[q[hea]]-q[hea]);
        while(hea<=tail&&a[q[tail]]-q[tail]<a[i]-i)
            --tail;
        q[++tail]=i;
    }
    for(LL i=2;i<=len;i++)
        dp[u]=max(dp[u],a[i]+min(i-1,len-i+1));
}
void Tarjan(LL u){
    //printf("%lld\n",u);
    low[u]=dfn[u]=++tot;
    for(LL i=head[u];i;i=dis[i].next){
        LL v=dis[i].to;
        if(v==fa[u])
            continue;
        if(!dfn[v]){
            dep[v]=dep[u]+1,
            fa[v]=u;
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }else
            low[u]=min(low[u],dfn[v]);
        if(low[v]>dfn[u]){
            ans=max(ans,dp[u]+dp[v]+1);
            dp[u]=max(dp[u],dp[v]+1);
        }
    }
    for(LL i=head[u];i;i=dis[i].next){
        LL v=dis[i].to;
        if(fa[v]!=u&&dfn[u]<dfn[v])
            Dp(u,v);
    }
}
int main(){
    n=Read(), m=Read();
    while(m--){
        LL kase=Read();
        LL pre=Read();
        for(LL i=2;i<=kase;++i){
            LL now=Read();
            Add(now,pre),Add(pre,now),
            pre=now;
        }
    }
    Tarjan(1);
    printf("%lld",ans);
    return 0;
}/*
15 3
9 1 2 3 4 5 6 7 8 3
7 2 9 10 11 12 13 10
5 2 14 9 15 10

8
*/

P4244 [SHOI2008]仙人掌图 II

标签:read   ext   name   show   next   string   algo   https   void   

原文地址:https://www.cnblogs.com/y2823774827y/p/10201005.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!