targan 算法模板

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
const int maxn = 10000+100;
int outdegree[maxn];

struct Tarjan
{
    int V;
    struct edge
    {
         int u, v;
         int opp(int k) { return k==u?v:u; }
    };
    vector<edge> e;          //
    vector<int> G[maxn];     //u连接的边
    int DFN[maxn], low[maxn], sk[maxn];
    int belong[maxn];
    bool instack[maxn];
    int top, Bcnt, Dindex;
    void init()
    {
        e.clear();
        for(int i=0; i<=V; i++) G[i].clear();
    }
    void add_edge(int u, int v)
    {
        e.push_back((edge){u, v});
        G[u].push_back(e.size()-1);
    }
    void dfs(int u)
    {
        DFN[u]=low[u]=++Dindex;
        instack[u] = true;
        sk[++top] = u;   //入栈
        for(int i=0; i<G[u].size(); i++)
        {
            int v = G[u][i];
            v = e[v].opp(u);          //u连接的边v
            if(!DFN[v])
            {
                dfs(v);
                low[u] = min(low[u], low[v]);
            }
            else if(instack[v])
                low[u] = min(low[u], DFN[v]);
        }
        if(DFN[u] == low[u])
        {
            Bcnt++;
            int v;
            do
            {
                v = sk[top--];
                instack[v] = false;
                belong[v]=Bcnt;

            }while(v!=u);
        }
    }
    void targan()
    {
        top = Bcnt = Dindex = 0;
        memset(DFN, 0, sizeof(DFN));
        for(int i=1; i<=V; i++)
            if(!DFN[i]) dfs(i);
    }
}ta;

int main()
{
    int n, m;  //n个顶点 m条边
    scanf("%d%d", &n, &m);
    ta.V = n;
    ta.init();
    for(int i=0; i<m; i++)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        ta.add_edge(u, v);
    }
    ta.targan();
    //他是先求后面的分量再求前面的分量
    return 0;
}

 

posted @ 2016-03-02 19:35  xing-xing  阅读(488)  评论(0编辑  收藏  举报