hdoj 1269 迷宫城堡(Kosaraju算法、Tarjan算法和Gabow算法(暂无))

图的强连通求解

->Kosaraju算法

    1.对原图G进行深度优先遍历,记录每个点的离开时间放入栈中。

    2.选栈顶元素,对反图GT进行遍历,删除能够遍历到的点,这些点构成一个强连通分量。

    3.若还有顶点没有被删除,循环 步骤2,否则算法结束

#include
using namespace std;

int n,m,s;
int stak[10010],top;
vector edge[10010],edge_T[10010]; //原图与反图
bool vis[10010]; //判断该点是否遍历过

void DFS_O(int v)
{
    vis[v] = true;
    for(int i=0; i0)
    {
        s = stak[--top];
        if(!vis[s])
        {
            DFS_T(s);
            ++cnt;//强联通连通分支数+1
        }
    }
    return cnt;
}

int main()
{
    int a,b;
    while(scanf("%d%d",&n,&m))
    {
        if(n==0&&n==0)
            break;
        for(int i=1;i<=n;++i)
        {
            edge[i].clear();
            edge_T[i].clear();
        }
        for(int i=0;i

->Tarjan算法

    1.找一个未被访问过的点v,若没有算法结束。

    2.初始化dfn[v]和low[v]

        对于v的所有邻接顶点u:

            ①未访问过,回到 步骤2,同时维护low[v];

            ②访问过但未删除,维护low[v].

            当low[v]==dfn[v]时 输出相应强连通分量。               

#include
using namespace std;

#define ll long long
#define M 10010
int n,m;
vector edge[M];
int cnt;//强连通分量个数
int top;
int Index;
int dfn[M],low[M];// dfn[v]表示顶点v被访问的时间   low[v]与顶点v邻接的未删除的顶点u的low[v]和low[u]的最小值
int stak[M],Belong[M];//Belong[]为每个结点所对应的强连通分量标号数组
bool Instak[M];

void Init()
{
    cnt = top = Index = 0;
    for(int i=1;i<=n;i++)
        low[i] = dfn[i] = 0;
}

void Tarjan(int u)
{
    stak[top++] = u;
    Instak[u] = 1;
    low[u] = dfn[u] = ++Index;
    for(int i=0;i

你可能感兴趣的:(acm_图论)