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 }

 

 

你可能感兴趣的:(2008)