您的位置:首页 > 其它

HDOJ-1269-迷宫城堡 解题报告

2014-11-16 16:49 417 查看
图论强连通模板题。中文题意不赘述。

我的解题思路:判断一个有向图是否强连通,可以用Tarjan算法计算出这个有向图的极大强连通分量个数是否只有一个。还有一种比较水的方法:判断一个有向图是否强连通,随便找一个点看一下能否搜索到原图中所有点,然后依旧是这个点看能否搜索到反图(原图的边是x->y那么反图为y->x)中的所有点。如果能的话说明该图强连通。

我的解题代码:Tarjan强连通分量算法,未缩点

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

using namespace std;

#define N 10002 

vector <int> e
;
int dfn
, low
;
int vis
;     //0代表未访问过,1代表访问过但是当前不在栈内,2代表访问过且在栈内
int index;
int Stack
;   //手写栈
int Stop;       //栈顶下标
int ans;
int n, m;

void InitRead();

void DataProcess();

void Tarjan(int x);

int main()
{
    while (~scanf("%d %d", &n, &m))
    {
        if (n == 0 && m == 0) break;
        InitRead();
        DataProcess();
    }
    return 0;
}

void InitRead()
{
    memset(vis, 0, sizeof(vis));
    ans = index = Stop = 0;
    for (int i=0; i<=n; ++i) e[i].clear();
    int a, b;
    for (int i=0; i<m; ++i)
    {
        scanf("%d %d", &a, &b);
        e[a].push_back(b);
    }
    return;
}

void DataProcess()
{
    for (int i=1; i<=n; ++i)
    {
        if (!vis[i])
        {
            Tarjan(i);
        }
    }
    printf("%s\n", ans == 1 ? "Yes" : "No");
    return;
}

void Tarjan(int x)
{
    int y;
    dfn[x] = low[x] = index++;
    vis[x] = 2;
    Stack[Stop++] = x;
    int size = e[x].size();
    for (int i=0; i<size; ++i)
    {
        if (!vis[e[x][i]])
        {
            Tarjan(e[x][i]);
            low[x] = min(low[x], low[e[x][i]]);
        }
        else if (vis[e[x][i]] == 2)
        {
            low[x] = min(low[x], dfn[e[x][i]]);
        }
    }
    if (dfn[x] == low[x])
    {
        ans++;
        do {
            y = Stack[--Stop];
            vis[y] = 1;
        } while (x != y);
    }
    return;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: