【學習】tarjan演算法

來源:互聯網
上載者:User

標籤:深度   解析   ret   強連通   強聯通   top   沒有   space   blog   

話說昨天練習的時候,有一道題是要求強連通分量預先處理的。然而那時我還不知道tarjan演算法為何物,於是糊出了如下求強連通分量的演算法。(時間複雜度O(n*logn))

 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=10010; 4 struct edge{ 5     int la,b; 6 }con[N<<1]; 7 int tot,fir[N]; 8 void add(int u,int v) 9 {10     con[++tot].la=fir[u];11     con[tot].b=v;12     fir[u]=tot;13 }14 int deep[N],bel[N],n,m;15 bool pass[N],vis[N];16 int get_bel(int pos)17 {18     if(bel[pos]!=pos) bel[pos]=get_bel(bel[pos]);19     return bel[pos];20 }21 int dfs(int pos,int fa)22 {23     vis[pos]=1;pass[pos]=1;24     deep[pos]=deep[fa]+1;25     bel[pos]=pos;26     int tmp;27     for(int i=fir[pos];i;i=con[i].la)28     {29         if(vis[con[i].b]&&!pass[con[i].b])30         {31             if(pass[get_bel(con[i].b)])32             {33                 if(deep[get_bel(con[i].b)]<deep[get_bel(pos)])34                  bel[pos]=get_bel(con[i].b);35             }36             continue;37         }38         if(!pass[con[i].b])39         {40             tmp=dfs(con[i].b,pos);41             if(pass[tmp]&&deep[tmp]<deep[get_bel(pos)]) bel[pos]=tmp;42         }43         else44         {45             if(deep[con[i].b]<deep[get_bel(pos)]) bel[pos]=con[i].b;46         }47     }48     pass[pos]=0;49     return get_bel(pos);50 }51 void solve()52 {53     dfs(1,0);54     for(int i=1;i<=n;i++) cout<<get_bel(i)<<endl;55 }56 int main()57 {58     int from,to;59     scanf("%d%d",&n,&m);60     for(int i=1;i<=m;i++)61     {62         scanf("%d%d",&from,&to);63         add(from,to);64     }65     solve();66     return 0;67 }

於是用這個演算法寫了那道題,居然AC了。(那題還要求單源最短路,卡不掉我的O(n*logn)預先處理2333)

(註:這個辣雞演算法就是用並查集把每一個點連向其所在強聯通分量的深度最小的點,再對樹邊,後向邊,橫叉邊都討論一遍(前向邊當橫叉邊處理))

然後我又學了tarjan演算法,便又寫了如下程式。

 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=10010; 4 int low[N],dfn[N],n,m; 5 struct edge{ 6     int la,b; 7 }con[N<<1]; 8 int tot,fir[N]; 9 void add(int from,int to)10 {11     con[++tot].la=fir[from];12     con[tot].b=to;13     fir[from]=tot;14 }15 stack<int>s;16 int bel[N],cnt;17 void tarjan(int pos)18 {19     s.push(pos);20     low[pos]=dfn[pos]=++cnt;21     for(int i=fir[pos];i;i=con[i].la)22     {23         if(bel[con[i].b]) continue;24         if(!dfn[con[i].b]) tarjan(con[i].b);25         low[pos]=min(low[pos],low[con[i].b]);26     }27     if(dfn[pos]==low[pos])28     {29         int po=s.top();s.pop();30         while(po!=pos)31         {32             bel[po]=pos;33             po=s.top();s.pop();34         }35         bel[pos]=pos;36     }37 }38 void solve()39 {40     while(!s.empty()) s.pop();41     tarjan(1);42     for(int i=1;i<=n;i++) cout<<bel[i]<<endl;43 }44 int main()45 {46     int from,to;47     scanf("%d%d",&n,&m);48     for(int i=1;i<=m;i++)49     {50         scanf("%d%d",&from,&to);51         add(from,to);52     }53     solve();54     return 0;55 }

短了很多。

然後就沒有然後了。(tarjan演算法的解析?網上多著呢。)

 

小結:大佬與蒟蒻的差距就體現在那個log。

【學習】tarjan演算法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.