Luo Gu 3388 tarjan cut point

Topic links: https://www.luogu.com.cn/problem/P3388

tarjan really fast hardware algorithm, the time complexity is O (| V | + | E |), so 1e4 2e5 nodes edges FIG fully cinch orz orz

Without seeking to cut a point map that is not necessarily communicating, so there is no point to continue tarjan visited, this time I wa a few times, because tarjan used only once before, in which I set the parameters from the default u = 1 began to build dfs tree. Only the root of every father is equal to its number, so that we can uniquely identify it, learned. Then in the following proof tarjan if used in processing rollback side is ①, Low [U] = min (Low [U], Low [V]) (usage strongly connected component) instead ②, low [u ] = min (low [u] , dfn [v]) , then will be what kind of error.

 

 

 

We both analog and Tarjan algorithm, one is low[u] = min( low[u], low[v] );, one is low[u] = min( low[u], dfn[v] );. (Reference prove Luo Gubo off)

Item 1:

① dfs(1),dfn[1] = 1,low[1] = 1。

② dfs(2),dfn[2] = 2,low[2] = 2。

③ dfs(3),dfn[3] = 3,low[3] = 3。

④ found back side 3 -> 1, low [3] = 1.

⑤ dfs(4),dfn[4] = 4,low[4] = 4。

⑥ dfs(5),dfn[5] = 5,low[5] = 5。

⑦ found back side 5 -> 3, low [5] = 1.

⑧ dfs (5) ends, back dfs (4), low [4] = 1.

⑨ dfs (4) end, back dfs (3), low [3] = 1.

⑩ dfs (3) end, so far found no cut points.

No. 2:

① dfs(1),dfn[1] = 1,low[1] = 1。

② dfs(2),dfn[2] = 2,low[2] = 2。

③ dfs(3),dfn[3] = 3,low[3] = 3。

④ found back side 3 -> 1, low [3] = 1.

⑤ dfs(4),dfn[4] = 4,low[4] = 4。

⑥ dfs(5),dfn[5] = 5,low[5] = 5。

⑦ found back side 5 -> 3, low [5] = 3.

⑧ dfs (5) ends, back dfs (4), low [4] = 3.

⑨ dfs (4) end, back dfs (3), low [4]> = dfn [3], found that a cut point 3, low [3] = 1.

And this figure, the correct answer is: 3 is a cut point.

So the first method we will be happy to Hack out.

Secondly, I rolled back when the plus side in the condition of the dfn [v] <dfn [u], time efficiency is improved by about 10%, which is obvious, because the only side to reach the rollback of the parent node It is accessed before the node, but this node is not already treated fa nodes.

code show as below:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef unsigned int ui;
 4 typedef long long ll;
 5 typedef unsigned long long ull;
 6 #define pf printf
 7 #define mem(a,b) memset(a,b,sizeof(a))
 8 #define prime1 1e9+7
 9 #define prime2 1e9+9
10 #define pi 3.14159265
11 #define lson l,mid,rt<<1
12 #define rson mid+1,r,rt<<1|1
13 #define scand(x) scanf("%llf",&x) 
14 #define f(i,a,b) for(int i=a;i<=b;i++)
15 #define scan(a) scanf("%d",&a)
16 #define mp(a,b) make_pair((a),(b))
17 #define P pair<int,int>
18 #define dbg(args) cout<<#args<<":"<<args<<endl;
19 #define inf 0x3f3f3f3f
20 const int maxn=2e4+10;
21 int n,m,t;
22 inline int read(){
23     int ans=0,w=1;
24     char ch=getchar();
25     while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
26     while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
27     return ans*w;
28 }
29 int low[maxn],dfn[maxn],iscut[maxn],head[maxn],nxt[200010];
30 int cnt=0;
31 int ans=0;
32 struct node{
33     int u,v;
34 }p[200010];
35 int e=0;
36 void addedge(int x,int y)
37 {
38     p[e].u=x;
39     p[e].v=y;
40     nxt[e]=head[x];
41     head[x]=e++;
42 }
43 void tarjan(int u,int fa)
44 {
45     dfn[u]=low[u]=++cnt;
46     int child=0;
47     for(int i=head[u];~i;i=nxt[i])
48     {
49         int v=p[i].v;
50         if(!dfn[v])
51         {
52             if(fa==u)child++;
53             tarjan(v,u);
54             low[u]=min(low[v],low[u]);
55             if(low[v]>=dfn[u]&&u!=fa)iscut[u]=1;
56         }
57         else if(dfn[v]<dfn[u]&&v!=fa)
58         {
59             low[u]=min(low[u],dfn[v]);    
60         }
61     }
62     if(u==fa&&child>1)iscut[u]=1;
63 }
64 int main()
65 {
66     //freopen("input.txt","r",stdin);
67     //freopen("output.txt","w",stdout);
68     std::ios::sync_with_stdio(false);
69     n=read(),m=read();
70     int x,y;
71     cnt=0;
72     ans=0;
73     mem(low,0);
74     mem(dfn,0);
75     mem(iscut,0);
76     mem(head,-1);
77     mem(nxt,-1);
78     f(i,1,m)
79     {
80         x=read(),y=read();
81         addedge(x,y);
82         addedge(y,x);
83      } 
84      f(i,1,n)
85      {
86          if(!dfn[i])tarjan(i,i);//图不一定连通,所以每个连通分量都要tarjan一次 
87       } 
88      f(i,1,n)
89      {
90          if(iscut[i])ans++;
91      }
92      pf("%d\n",ans);
93      f(i,1,n)
94      if(iscut[i])pf("%d ",i);
95      return 0;
96 } 

 

Guess you like

Origin www.cnblogs.com/randy-lo/p/12583899.html