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; 
}

Tarjan算法模板: 

const int N = 1e5 + 5;
vector<int> g[N];
int low[N], dfn[N], stk[N], cmp[N], cnt = 0, top = 0, tot = 0;
bool vis[N];
void tarjan(int u) {
    low[u] = dfn[u] = ++cnt;
    stk[++top] = u;
    vis[u] = true; //标记是否在栈中
    for (int v : g[u]) {
        if(!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(vis[v]) low[u] =  min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]) {
        cmp[u] = ++tot;
        vis[u] = false;
        while(stk[top] != u) {
            cmp[stk[top]] = tot;
            vis[stk[top--]] = false;
        }
        top--;
    }
}

 例题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

相关文章:

  • 2022-01-08
  • 2021-12-19
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-02-09
  • 2021-12-03
  • 2022-12-23
猜你喜欢
  • 2021-11-08
  • 2021-11-28
  • 2021-12-02
  • 2021-11-03
  • 2021-11-24
  • 2021-06-22
  • 2021-12-27
相关资源
相似解决方案