bzoj 1023: [SHOI2008]cactus仙人掌图

这个题真的不会啊 简而言之就是树形DP+环形Dp

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<queue>
 7 #include<algorithm>
 8 #include<vector>
 9 #define M 50008
10 #define EPS 1e-10
11 #define MO 10000
12 #define ll long long
13 using namespace std;
14 ll read()
15 {
16     char ch=getchar();
17     ll x=0,f=1;
18     for(;ch<'0'||ch>'9';ch=getchar())
19         if(ch=='-')
20           f=-1;
21     for(;ch>='0'&&ch<='9';ch=getchar())
22         x=x*10+ch-'0';
23     return x*f;
24 }
25 int fa[M],m,n,dfn[M],low[M],T,head[M],next[200*M],u[200*M],cnt,ans,f[M],h[M],a[2*M],q[2*M];
26 void jia(int a1,int a2)
27 {
28     cnt++;
29     next[cnt]=head[a1];
30     head[a1]=cnt;
31     u[cnt]=a2;
32 }
33 void dp(int x,int y)
34 {
35     int len=h[y]-h[x]+1;
36     for(int i=y;i!=x;i=fa[i])
37         a[len--]=f[i];
38     a[len]=f[x];
39     len=h[y]-h[x]+1;
40     for(int i=len+1;i<=2*len;i++)
41       a[i]=a[i-len];
42     int h=1,t=1;
43     q[1]=1;
44     for(int i=2;i<=2*len;i++)
45       {
46         for(;h<=t&&i-q[h]>len/2;h++);
47         ans=max(i-q[h]+a[i]+a[q[h]],ans);
48         for(;h<=t&&a[q[t]]-q[t]<=a[i]-i;t--);
49         q[++t]=i;
50       }
51     for(int i=2;i<=len;i++)
52       f[x]=max(f[x],a[i]+min(i-1,len-i+1));
53 }
54 void tarjin(int x)
55 {
56     dfn[x]=low[x]=++T;
57     for(int i=head[x];i;i=next[i])
58       if(u[i]!=fa[x])
59         {
60             if(!dfn[u[i]])
61               {
62                 fa[u[i]]=x;
63                 h[u[i]]=h[x]+1;
64                 tarjin(u[i]);
65                 low[x]=min(low[x],low[u[i]]);
66               }
67             else
68               low[x]=min(low[x],dfn[u[i]]);
69             if(low[u[i]]>dfn[x])
70               {
71                 ans=max(ans,f[x]+f[u[i]]+1);
72                 f[x]=max(f[x],f[u[i]]+1);
73               }
74         }
75     for(int i=head[x];i;i=next[i])
76       if(fa[u[i]]!=x&&dfn[u[i]]>dfn[x])
77         dp(x,u[i]);
78 }
79 int main()
80 {
81     n=read();
82     m=read();
83     for(int i=1;i<=m;i++)
84       {
85         int k=read(),a1=read();
86         for(int j=2;j<=k;j++)
87           {
88             int a2=read();
89             jia(a1,a2);
90             jia(a2,a1);
91             a1=a2;
92           }
93       }
94     tarjin(1);
95     printf("%d\n",ans);
96     return 0;
97 }
98 

 

posted @ 2016-07-09 20:34  xiw5  阅读(139)  评论(0编辑  收藏  举报