zoukankan      html  css  js  c++  java
  • bzoj1023: [SHOI2008]cactus仙人掌图

    传送门

    求仙人掌的直径。

    求一遍边双,建立圆方树,然后在树上dp;

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    #include<ctime>
    const int N=100007; 
    typedef long long LL;
    using namespace std;
    int n,m;
    
    template<typename T> void read(T &x) {
        T f=1; x=0; char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    int ecnt=1,fir[N],nxt[N<<1],to[N<<1]; 
    void add(int u,int v) {
        nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
        nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u;
    }
    
    int ec,fi[N],nx[N],tt[N]; 
    void add_edge(int u,int v) {
        nx[++ec]=fi[u]; fi[u]=ec; tt[ec]=v;
    }
    
    int tot,dfn[N],low[N],dfs_clock,sta[N],top;
    void tarjan(int x,int f) {
        dfn[x]=low[x]=++dfs_clock;
        sta[++top]=x;
        for(int i=fir[x];i;i=nxt[i]) {
            int y=to[i];
            if(!dfn[y]) {
                tarjan(y,i^1);
                if(low[y]>dfn[x]) add_edge(x,y),top--;  
                low[x]=min(low[x],low[y]);
                if(low[y]==dfn[x]) {
                    add_edge(x,++tot);
                    while(top) {
                        int z=sta[top--];
                        add_edge(tot,z);
                        if(z==y) break;
                    }
                }
            }
            else if(i^f) low[x]=min(low[x],dfn[y]);
        }
    }
    
    int f[N],que[N],ql,qr,tmp[N],tp,ans;
    void dfs(int x) {
        for(int i=fi[x];i;i=nx[i]) 
            dfs(tt[i]);
        if(x<=n) {
            int cd=0;
            for(int i=fi[x];i;i=nx[i]) {
                cd=max(cd,f[tt[i]]+1);
                if(cd>f[x]) swap(cd,f[x]);
            }
            ans=max(ans,f[x]+cd); 
        }
        else {
            ql=1; qr=0; tp=1;
            for(int i=fi[x];i;i=nx[i]) tmp[tp++]=tt[i];
            for(int i=0;i<tp;i++) tmp[tp+i]=tmp[i];
            for(int i=1;i<=(tp>>1)+tp;i++) {
                while(ql<=qr&&(i-que[ql])*2>tp) ql++;
                if(i>(tp>>1)) ans=max(ans,f[tmp[i]]+f[tmp[que[ql]]]+i-que[ql]);
                while(ql<=qr&&f[tmp[que[qr]]]-que[qr]<=f[tmp[i]]-i) qr--;
                que[++qr]=i;
            }
            for(int i=1;i<=(tp>>1);i++) f[x]=max(f[x],f[tmp[i]]+i-1);
            for(int i=(tp>>1)+1;i<tp;i++) f[x]=max(f[x],f[tmp[i]]+tp-i-1);
        }
    }
    
    int main() {
        read(n); read(m); tot=n;
        while(m--) {
            int k,x,y;
            read(k); read(x);
            for(int i=k-1;i;i--) {
                read(y); add(x,y); x=y; 
            }
        }
        for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,0);
        dfs(1);
        printf("%d
    ",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
    10 1
    10 1 2 3 4 5 6 7 8 9 10
    */
    View Code
  • 相关阅读:
    makefile vpath变量
    博客园 文章和随笔区别
    Linux OpenGL 实践篇-6 光照
    HTC Vive 叠影器无法创建设备
    Mybatis注解
    MyBatis缓存
    MyBatis关联映射
    动态sql
    MyBatis智能标签
    Mybatis模糊查询及自动映射
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8231087.html
Copyright © 2011-2022 走看看