码迷,mamicode.com
首页 > 编程语言 > 详细

算法笔记--强连通分量分解

时间:2017-10-08 14:48:21      阅读:241      评论:0      收藏:0      [点我收藏+]

标签:clu   blank   memset   ems   for   clear   stream   span   tar   

Kosaraju算法

详见《挑战程序设计竞赛》p320

模板:

const int N=1e5+5;
int n,m;
vector<int>g[N];
vector<int>rg[N];
vector<int>vs;
bool vis[N];
int cmp[N];

void add_edge(int u,int v)
{
    g[u].pb(v);
    rg[v].pb(u);
} 

void dfs(int u)
{
    vis[u]=true;
    for(int i=0;i<g[u].size();i++)
    if(!vis[g[u][i]])dfs(g[u][i]);
    vs.pb(u);
}

void rdfs(int u,int k)
{
    vis[u]=true;
    cmp[u]=k;
    for(int i=0;i<rg[u].size();i++)
    if(!vis[rg[u][i]])rdfs(rg[u][i],k);
}

int scc()
{
    mem(vis,false);
    vs.clear();
    for(int i=1;i<=n;i++)if(!vis[i])dfs(i);
    
    mem(vis,false);
    int k=0;
    for(int i=vs.size()-1;i>=0;i--)if(!vis[vs[i]])rdfs(vs[i],k++);
    return k; 
}

例题1:POJ 2186 Popular Cows

代码:

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
#define ll long long
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
const int N=1e5+5;
int n,m;
vector<int>g[N];
vector<int>rg[N];
vector<int>vs;
bool vis[N];
int cmp[N];

void add_edge(int u,int v)
{
    g[u].pb(v);
    rg[v].pb(u);
} 

void dfs(int u)
{
    vis[u]=true;
    for(int i=0;i<g[u].size();i++)
    if(!vis[g[u][i]])dfs(g[u][i]);
    vs.pb(u);
}

void rdfs(int u,int k)
{
    vis[u]=true;
    cmp[u]=k;
    for(int i=0;i<rg[u].size();i++)
    if(!vis[rg[u][i]])rdfs(rg[u][i],k);
}

int scc()
{
    mem(vis,false);
    vs.clear();
    for(int i=1;i<=n;i++)if(!vis[i])dfs(i);
    
    mem(vis,false);
    int k=0;
    for(int i=vs.size()-1;i>=0;i--)if(!vis[vs[i]])rdfs(vs[i],k++);
    return k; 
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>m;
    int u,v;
    for(int i=0;i<m;i++)cin>>u>>v,add_edge(u,v);
    
    int t=scc();
    int ans=0;
    for(int i=1;i<=n;i++)if(cmp[i]==t-1)ans++,u=i;
    
    mem(vis,false);
    rdfs(u,0);
    
    for(int i=1;i<=n;i++)if(!vis[i])ans=0;
    cout<<ans<<endl; 
    return 0;
} 
View Code

例题2:

算法笔记--强连通分量分解

标签:clu   blank   memset   ems   for   clear   stream   span   tar   

原文地址:http://www.cnblogs.com/widsom/p/7637280.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!