羅区3388 tarjanカットポイント

トピックリンク:https://www.luogu.com.cn/problem/P3388

本当に速いハードウェアアルゴリズムをtarjan、時間の複雑さはO(| V | + | E |)ので、1E4 2E5のノードは、図完全に楽勝ORZ ORZエッジ

tarjanは一度だけ前に使用しているため、必ずしも通信していない点マップをカットしようとせずに、その訪問tarjanを継続するためにはポイントがありません、この時間は、私は、数回WA、私はデフォルトのパラメータを設定しますuが1でDFSツリーを構築し始めました=。すべての父の唯一のルートは、我々が独自に学んだ、それを識別できるようにすることを、その数に等しいです。次に、ロールバックサイドを処理する際に使用される場合、次の証明tarjanである①、ロー[U] =分(低[U]、低[V]) 使用強連結成分)の代わりに②、低[U =分(低[U] 、DFN [V]) 、次にどのようなエラーのであろう。

 

 

 

我々は両方のアナログとTarjanのアルゴリズム、1はlow[u] = min( low[u], low[v] );、1ですlow[u] = min( low[u], dfn[v] );(参考羅Guboをオフに証明します)

項目1:

①DFS(1)、DFN [1] = 1、ロー[1] = 1。

②DFS(2)、DFN [2] = 2、ロー[2] = 2。

③DFS(3)、DFN [3] = 3、低い[3] = 3。

[3] = 1> 1、低 - ④背面側3を見つけました。

⑤DFS(4)、DFN [4] = 4、ロー[4] = 4。

⑥DFS(5)、DFN [5] = 5、ロー[5] = 5。

[5] = 1>図3に示すように、低 - ⑦背側5を発見しました。

⑧DFS(5)の端部、バックDFS(4)、ロー[4] = 1。

⑨DFS(4)エンド、バックDFS(3)、低い[3] = 1。

⑩DFS(3)末端、これまでにないカットポイントが見つかりません。

ランク2:

①DFS(1)、DFN [1] = 1、ロー[1] = 1。

②DFS(2)、DFN [2] = 2、ロー[2] = 2。

③DFS(3)、DFN [3] = 3、低い[3] = 3。

[3] = 1> 1、低 - ④背面側3を見つけました。

⑤DFS(4)、DFN [4] = 4、ロー[4] = 4。

⑥DFS(5)、DFN [5] = 5、ロー[5] = 5。

[5] = 3>図3に示すように、低 - ⑦背側5を発見しました。

⑧DFS(5)の端部、バックDFS(4)、ロー[4] = 3。

⑨DFS(4)エンド、バックDFS(3)、ロー[4]> = DFN [3]、見られるカットポイント3、低い[3] = 1。

そして、この図は、正しい答えは:3カット点です。

だから、最初の方法は、我々はハックさせていただきます。

DFNの条件でプラス側が[V] <DFN [U]は、時間効率が明らかである約10%改善されている場合にのみ側面は、親ノードのロールバックに到達するので、第二に、私は、ロールバックこれは、ノードの前にアクセスされるが、このノードは既にFAノードが処理されていません。

コードは以下の通りであります:

 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 } 

 

おすすめ

転載: www.cnblogs.com/randy-lo/p/12583899.html