SHOI 2008 Cactus BZOJ 1023

1023: [SHOI2008]cactus
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 2564 Solved: 1062
Description
If at most one edge of an undirected connected graph appears in a simple cycle, we call it a cactus
Figure (cactus).Simple loops are loops that do not repeat through any vertex on the graph.
For example, the first example above is a fairy figure, while the second is not -- notice that it has three simple loops: (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), while (2, 3) appear in both
In a simple loop of 1.Also, the third graph is not a fairy graph because it is not connected.Obviously, every side of the fairy map, or this fairy
The bridge of a human diagram, or in a simple circuit only, must be one of the two.Define the distance between two points on the graph as the greatest distance between them
The distance of the short path.Define the diameter of a graph as the distance between the two farthest points in the graph.Now let's assume that each edge of the fairy chart has a weight of 1
Your task is to find the diameter of the given fairy chart.
Input
The first line of input consists of two integers n and m (1 < n < 50000 and 0 < m < 10000).Where n represents the number of vertices, we agree on the top of the graph
Points will be numbered from 1 to n.Next, there are m rows in total.Represents m paths.Each row begins with an integer k (2 < K < 1000), which represents the path
Number of vertices of.Next are k integers from 1 to n, corresponding to one vertex, and the adjacent vertices indicate that there is an edge connecting the two vertices
.A path may go through a vertex several times, for example, for the first example, the first path goes from 3 to 8 and then from 8 to 3, but we do
Ensure that all edges will appear on one path and not on two paths or twice on one path.
Output
You only need to output a number that represents the diameter and length of the fairy chart.
Sample Input
15 3
9 1 2 3 4 5 6 7 8 3
7 2 9 10 11 12 13 10
5 2 14 9 15 10 8
10 1
10 1 2 3 4 5 6 7 8 9 10
Sample Output
8
9
HINT
Note for the first example: As shown in the figure, the shortest path length for points 6 and 12 is 8, so the diameter of this figure is 8.
[Note] Pascal speakers should be aware that your program may experience stack overflow when processing large data.
If you need to resize the stack space, you can add a sentence at the beginning of the program: {$M 5000000}, of which 5000000 is
Refers to the size of stack space, please choose the appropriate value according to your program.

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 2222222
int head[N],to[N],next[N];
int n,m,tot,cnt,ans;
int dis[N],cir[N];
int dfn[N],low[N],visx,fa[N];
inline void Add_Edge(int u,int v){to[cnt]=v;next[cnt]=head[u];head[u]=cnt++;}
struct Data{
    int p,w;
}q[N];
inline void read(){
    memset(head,-1,sizeof head );
    scanf("%d%d",&n,&m);
    for(int i=1,a,b,c;i<=m;i++){
        scanf("%d%d",&a,&b);
        for(int j=2;j<=a;j++){
            scanf("%d",&c);
            Add_Edge(b,c);Add_Edge(c,b);b=c;
        }
    }
}
inline void GetCircle(){
    int h=1,t=1;
    for(int i=1;i<=tot;i++) cir[tot+i]=cir[i];//Spread chain into rings
    for(int i=1;i<=(tot<<1);i++){
        while(h<t&&i-q[h].p>(tot>>1)) h++;
        while(h<t&&q[t].w<=dis[cir[i]]-i) t--;
        q[++t].p=i; q[t].w=dis[cir[i]]-i;
        ans=max(ans,dis[cir[i]]+i+q[h].w);
    }
}
inline void DFS(int u){
    low[u]=dfn[u];
    for(int i=head[u];~i;i=next[i]){
        int v=to[i];
        if(fa[v]!=0&&v!=fa[u]) low[u]=min(low[u],dfn[v]);
        if(fa[v]==0){
            fa[v]=u; dfn[v]=dfn[u]+1; DFS(v);
            low[u]=min(low[u],low[v]);
        }
    }
    for(int i=head[u];~i;i=next[i]){
        int v=to[i];
        if(fa[v]==u&&low[v]>dfn[u]){//Bridge
            ans=max(ans,dis[v]+1+dis[u]);
            dis[u]=max(dis[u],dis[v]+1);
        }
        if(fa[v]!=u&&dfn[u]<dfn[v]){//Circle
            tot=0;
            while(v!=fa[u]) cir[++tot]=v,v=fa[v];//cirPoint on temporary storage ring
            GetCircle();//Next, deal with the points on the ring
            for(int j=1;j<tot;j++)
                dis[u]=max(dis[u],dis[cir[j]]+min(j,tot-j));
        }
    }
}
inline void GO(){
    fa[1]=-1;
    DFS(1);
    cout<<ans<<endl;
}
int main(){
    read();
    GO();
    return 0;
}

Posted by released on Wed, 03 Jul 2019 10:18:56 -0700