[Tree dp] [Tarjan] [monotone queue] Bzoj 1023 cactus cacti

Description

  If no one at most only appear to a connected graph any edge in a simple circuit (simple cycle), we would say this picture shows Cactus
diagram (cactus). Refers to the so-called simple loop through the loop will not be repeated in any of a vertex on FIG.

 

  For example, the first example above is an immortal FIG rather than second - note that it has three simple circuit: (4,3,2,1,6
, 5,4), (7, 8,9,10,2,3,7) and (4,3,7,8,9,10,2,1,6,5,4), and (2,3) in the first two simultaneous
th simple loop in. In addition, the third diagram is not immortal chart, because it is not connected graph. Clearly, each side on the fairy drawing, or is this immortal
human figure bridge (bridge), or in and only a simple circuit, the two will be one. FIG defined as the distance between the two points between these two points is the most
short distance path. FIG diameter defining a distance between two points furthest away from this FIG. Now we assume that immortal figure the weight of each edge is 1
, your task is to find a given diameter figure immortal.

 

 

answer

  • If the edges are round and then as an ordinary tree dp
  • For the ring, then lifted him out alone to consider, first of all to calculate the contribution of the ring, and then update the ring most vertex
  • Updated, on this point directly take on the ring dp value , and then calculate the shortest path between two points , after adding the update
  • Contribute, that is, max (f [i] + f [j] + dis (i, j)), dis (i, j) = min (abs (deep [i] -deep [j]), size [ring] -abs (deep [i] -deep [j]))
  • You can maintain a monotonous queue, according to the depth into the stack

 

Code

 

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N=60010;
 6 struct edge{int to,from;}e[N*8];
 7 int n,m,L,R,cnt=1,ans=1,head[N],Q[N*2],q[N*2],f[N],Fa[N],deep[N],dfn[N],low[N];
 8 void insert(int x,int y)
 9 {
10     e[++cnt].to=y,e[cnt].from=head[x],head[x]=cnt;
11     e[++cnt].to=x,e[cnt].from=head[y],head[y]=cnt;
12 }
13 void dp(int x,int y)
14 {
15     int r=0;
16     for (int i=y;i!=x;i=Fa[i]) Q[++r]=i; Q[++r]=x;
17     reverse(&Q[1],&Q[r+1]);
18     for (int i=1;i<=r;i++) Q[i+r]=Q[i];
19     L=1,R=0;
20     for (int i=1;i<=r*2;i++)
21     {
22         while (L<=R&&i-q[L]>r/2) ++L;
23         if (L<=R) ans=max(ans,f[Q[i]]+f[Q[q[L]]]+i-q[L]);
24         while (L<=R&&f[Q[i]]-i>f[Q[q[R]]]-q[R]) R--;
25         q[++R]=i;
26     }
27     for (int i=y;i!=x;i=Fa[i]) f[x]=max(f[x],f[i]+min(deep[i]-deep[x],1+deep[y]-deep[i]));
28 }
29 void dfs(int x,int fa)
30 {
31     Fa[x]=fa,dfn[x]=low[x]=++dfn[0],deep[x]=deep[fa]+1;
32     for (int i=head[x];i;i=e[i].from) 
33     {
34         if (!dfn[e[i].to]) dfs(e[i].to,x),low[x]=min(low[x],low[e[i].to]); else if (e[i].to!=fa) low[x]=min(low[x],dfn[e[i].to]);
35         if (low[e[i].to]>dfn[x]) ans=max(ans,f[x]+f[e[i].to]+1),f[x]=max(f[x],f[e[i].to]+1);
36     }
37     for (int i=head[x];i;i=e[i].from) if (Fa[e[i].to]!=x&&dfn[x]<dfn[e[i].to]) dp(x,e[i].to);
38 }
39 int main()
40 {
41     scanf("%d%d",&n,&m);
42     for (int i=1,k,x,y;i<=m;i++)
43     {
44         scanf("%d%d",&k,&x);
45         for (int j=1;j<k;j++) scanf("%d",&y),insert(x,y),x=y;
46     }
47     dfs(1,0),printf("%d",ans);
48 }

 

Guess you like

Origin www.cnblogs.com/Comfortable/p/11367500.html