• BZOJ 1023 [SHOI2008]cactus仙人掌图 DP+单调队列


    这题不能用普通的tarjan来缩点,因为看第一个样例普通tarjan会跪的很惨。。

    然后乱yy一个缩点就好了。

    桥边和环上的边分开处理,挺容易看懂的。。。

    神犇都说这题水,我这弱菜觉得一点都不水,,,

    View Code
     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <cstdlib>
     5 #include <algorithm>
     6  
     7 #define N 2222222
     8  
     9 using namespace std;
    10  
    11 int head[N],to[N],next[N];
    12 int n,m,cnt,tot,ans;
    13 int dis[N],cir[N];
    14 int low[N],dfn[N],fa[N],tim;
    15  
    16 struct Q
    17 {
    18     int p,w;
    19 }q[N];
    20  
    21 inline void add(int u,int v)
    22 {
    23     to[cnt]=v; next[cnt]=head[u]; head[u]=cnt++;
    24 }
    25  
    26 inline void read()
    27 {
    28     memset(head,-1,sizeof head);
    29     scanf("%d%d",&n,&m);
    30     for(int i=1,a,b,c;i<=m;i++)
    31     {
    32         scanf("%d%d",&a,&b);
    33         for(int j=2;j<=a;j++)
    34         {
    35             scanf("%d",&c);
    36             add(b,c); add(c,b); b=c;
    37         }
    38     }
    39 }
    40  
    41 inline void getcir()
    42 {
    43     int h=1,t=1;
    44     for(int i=1;i<=tot;i++) cir[tot+i]=cir[i];
    45     for(int i=1;i<=(tot<<1);i++)
    46     {
    47         while(h<t&&i-q[h].p>(tot>>1)) h++;
    48         while(h<t&&q[t].w<=dis[cir[i]]-i) t--;
    49         q[++t].p=i; q[t].w=dis[cir[i]]-i;
    50         ans=max(ans,dis[cir[i]]+i+q[h].w);
    51     }
    52 }
    53  
    54 inline void dfs(int u)
    55 {
    56     low[u]=dfn[u];
    57     for(int i=head[u];~i;i=next[i])
    58     {
    59         if(fa[to[i]]!=0&&to[i]!=fa[u]) low[u]=min(low[u],dfn[to[i]]);
    60         if(fa[to[i]]==0)
    61         {
    62             fa[to[i]]=u; dfn[to[i]]=dfn[u]+1; dfs(to[i]); 
    63             low[u]=min(low[u],low[to[i]]);
    64         }
    65     }
    66     for(int i=head[u];~i;i=next[i])
    67     {
    68         if(fa[to[i]]==u&&low[to[i]]>dfn[u])//bridge
    69         {
    70             ans=max(ans,dis[to[i]]+1+dis[u]);
    71             dis[u]=max(dis[u],dis[to[i]]+1);
    72         }
    73         if(fa[to[i]]!=u&&dfn[u]<dfn[to[i]])//circle
    74         {
    75             int x=to[i]; tot=0;
    76             while(x!=fa[u]) cir[++tot]=x,x=fa[x];
    77             getcir();
    78             for(int j=1;j<tot;j++) dis[u]=max(dis[u],dis[cir[j]]+min(j,tot-j));
    79         }
    80     }
    81 }
    82  
    83 inline void go()
    84 {
    85     fa[1]=-1;
    86     dfs(1);
    87     cout<<ans<<endl;
    88 }
    89  
    90 int main()
    91 {
    92     read(),go();
    93     return 0;
    94 }
  • 相关阅读:
    实验四 代码评审
    实验三、UML 建模工具的安装与使用
    结对编程 第二阶段
    结对编程第一阶段
    实验一 GIT代码版本管理
    实验五 单元测试
    实验四 代码评审
    实验三 UML 建模工具的安装与使用
    结对编程阶段二
    结对编程第一阶段
  • 原文地址:https://www.cnblogs.com/proverbs/p/2945066.html
Copyright © 2020-2023  润新知