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

    1023: [SHOI2008]cactus仙人掌图
    思路:先求出非环上的最长链,然后环上用单调队列优化dp。
    代码:

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(4)
    #include<bits/stdc++.h>
    using namespace std;
    #define y1 y11
    #define fi first
    #define se second
    #define pi acos(-1.0)
    #define LL long long
    //#define mp make_pair
    #define pb push_back
    #define ls rt<<1, l, m
    #define rs rt<<1|1, m+1, r
    #define ULL unsigned LL
    #define pll pair<LL, LL>
    #define pli pair<LL, int>
    #define pii pair<int, int>
    #define piii pair<pii, int>
    #define pdd pair<double, double>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define debug(x) cerr << #x << " = " << x << "
    ";
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    //head
    
    const int N = 5e4 + 5;
    vector<int> g[N];
    int fa[N], deep[N], dp[N], a[N*2], n, m, t, ans;
    int dfn[N], low[N], cnt;
    inline void DP(int u, int v) {
        int t = 0;
        for (int i = v; i != u; i = fa[i]) a[++t] = i;
        a[++t] = u;
        for (int i = 1; i <= t; ++i) a[i+t] = a[i];
        deque<int> q;
        for (int i = 1; i <= 2*t; ++i) {
            while(!q.empty() && i-q.front() > t/2) q.pop_front();
            if(!q.empty()) ans = max(ans, dp[a[i]]+dp[a[q.front()]]+i-q.front());
            while(!q.empty() && dp[a[q.back()]]-q.back() <= dp[a[i]]-i) q.pop_back();
            q.push_back(i);
        }
        for (int i = v; i != u; i = fa[i]) {
            dp[u] = max(dp[u], dp[i]+min(deep[i]-deep[u], deep[v]-deep[i]+1));
        }
    }
    inline void tarjan(int u, int o) {
        fa[u] = o;
        deep[u] = deep[o]+1;
        dfn[u] = low[u] = ++cnt;
        for (int i = 0; i < g[u].size(); ++i) {
            int v = g[u][i];
            if(v == o) continue;
            if(!dfn[v]) {
                tarjan(v, u);
                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 (int i = 0; i < g[u].size(); ++i) {
            int v = g[u][i];
            if(fa[v] != u && dfn[v] > dfn[u]) {
                DP(u, v);
            }
        }
    }
    int main() {
        while(~scanf("%d %d", &n, &m)) {
            cnt = ans = 0;
            for (int i = 1; i <= m; ++i) {
                scanf("%d", &t);
                for (int i = 1; i <= t; ++i) scanf("%d", &a[i]);
                for (int i = 2; i <= t; ++i) g[a[i-1]].pb(a[i]), g[a[i]].pb(a[i-1]);
            }
            tarjan(1, 0);
            printf("%d
    ", ans);
            for (int i = 1; i <= n; ++i) g[i].clear(), low[i] = dfn[i] = dp[i] = 0;
        }
        return 0;
    }
    
    
  • 相关阅读:
    JSP版LCX:端口转发神器 KPortTran
    使用 JavaScript 实现对 PDF 的全文索引
    伙伴分配器的一个极简实现
    java创建线程的三种方式及其对照
    【版本号公布】Jeecg-P3 1.0 公布,J2EE微服务框架(插件开发)
    linux c 获取当前执行进程总数
    C++入门学习——模板
    GSON学习笔记之初识GSON
    Python学习笔记_Python对象
    怎样在OTN站点高速找到asm包并下载 (Oracle RAC)
  • 原文地址:https://www.cnblogs.com/widsom/p/11461334.html
Copyright © 2011-2022 走看看