zoukankan      html  css  js  c++  java
  • IOI2008 Island 岛屿

    题目描述:

    bz

    luogu

    题解:

    裸的基环树直径。

    代码:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 1000050;
    template<typename T>
    inline void read(T&x)
    {
        T f = 1,c = 0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
        x = f*c;
    }
    int n,hed[N],cnt=1;
    ll ans;
    struct EG
    {
        int to,nxt;
        ll w;
    }e[2*N];
    void ae(int f,int t,ll w)
    {
        e[++cnt].to = t;
        e[cnt].nxt = hed[f];
        e[cnt].w = w;
        hed[f] = cnt;
    }
    int sta[2*N],tl,rt;
    ll ste[N];
    bool vis[N],cir[N],use[N];
    int dfs0(int u,int pre)
    {
        if(vis[u])
        {
            rt = u;
            return 1;
        }
        vis[u] = 1;
        for(int j=hed[u],now;j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(j==pre)continue;
            if((now=dfs0(to,j^1)))
            {
                if(now==1)
                {
                    sta[++tl] = u;
                    ste[tl] = e[j].w;
                    cir[u] = 1;
                    if(u!=rt)return 1;
                }
                return 2;
            }
        }
        return 0;
    }
    int fa[N];
    ll dp[N],sum[2*N],st[2*N],h,l,now;
    void bfs(int u)
    {
        h = 1,l = 0;
        st[++l] = u;
        use[u]=1;
        while(h<=l)
        {
            u = st[h++];
            for(int j=hed[u];j;j=e[j].nxt)
            {
                int to = e[j].to;
                if(use[to]||cir[to])continue;
                use[to] = 1;
                fa[to] = u;
                st[++l] = to;
            }
        }
        for(int i=l;i>=1;i--)
        {
            u = st[i];
            for(int j=hed[u];j;j=e[j].nxt)
            {
                int to = e[j].to;
                if(cir[to]||to==fa[u])continue;
                ll tmp = dp[to]+e[j].w;
                now = max(now,dp[u]+tmp);
                dp[u]=max(dp[u],tmp);
            }
        }
    }
    int main()
    {
    //  freopen("tt.in","r",stdin);
        read(n);
        for(int f,w,i=1;i<=n;i++)
        {
            read(f),read(w);
            ae(f,i,w),ae(i,f,w);
        }
        for(int i=1;i<=n;i++)if(!use[i])
        {
            tl=0;now=0;
            dfs0(i,0);
            for(int j=1;j<=tl;j++)
                bfs(sta[j]),sta[j+tl]=sta[j];
            if(tl==1)
            {
                now = max(now,dp[sta[1]]+ste[1]);
                ans+=now;
                continue;
            }
            for(int j=1;j<=tl;j++)sum[j]=sum[j-1]+ste[j];
            for(int j=1;j<=tl;j++)sum[j+tl]=sum[j+tl-1]+ste[j];
            h = 1,l = 0;
            for(int j=1;j<=2*tl;j++)
            {
                while(h<l&&st[h]+tl<=j)h++;
                if(h<=l)now = max(now,dp[sta[j]]+sum[j]+dp[sta[st[h]]]-sum[st[h]]);
                while(h<l&&dp[sta[st[l]]]-sum[st[l]]<dp[sta[j]]-sum[j])l--;
                st[++l] = j;
            }
            ans+=now;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    高亮表格行或列
    点击表格获取表格行或列索引
    文本框仅可接收decimal
    实现表格自动计算
    实现一个超简单的开关
    Nginx反向代理中proxy_set_header参数说明
    两个目录中,删除其中一个目录中同名文件的做法
    监控某个目录是否被更改
    centos下升级git版本的操作记录
    linux下core file size设置笔记
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10777132.html
Copyright © 2011-2022 走看看