HDU1269 迷宫城堡

HDU1269 迷宫城堡

题目大意

给定 有向图 中的 n 个点, m 条边, 求图的 强连同分量 是否为 1.

题目思路

一道裸的 tarjan 题, 需要注意的是边的存储, LOW的含义.

代码

#include <cstdio>
#include <cstring>
#include <stack>
#include <cmath>
#define MAXN 10100
#define MAXM 100100
using namespace std;
struct Edge{
    int v, next;
}edge[MAXM];
int vis[MAXN];
int head[MAXN];
int DFN[MAXN];
int LOW[MAXN];
int cntSCC, cntVertex, cntEdge;
stack<int> stk;
void init(){
    memset(vis, 0, sizeof(vis));
    memset(head, -1, sizeof(head));
    memset(DFN, 0, sizeof(DFN));
    memset(LOW, 0, sizeof(LOW));
    cntEdge = cntSCC = 0;
    cntVertex = 1;
    while(!stk.empty())
        stk.pop();
}
void addEdge(int u, int v){
    edge[cntEdge].next = head[u];
    edge[cntEdge].v = v;
    head[u] = cntEdge;
    cntEdge++;
}
void tarjan(int loc){
    DFN[loc] = LOW[loc] = cntVertex++;
    vis[loc] = 1;
    stk.push(loc);
    for(int i = head[loc]; i != -1; i = edge[i].next){
        if(!DFN[edge[i].v]){
            tarjan(edge[i].v);
            LOW[loc] = min(LOW[loc], LOW[edge[i].v]);
        }
        else if(vis[edge[i].v]){
            LOW[loc] = min(LOW[loc], DFN[edge[i].v]);
        }
    }
    if(DFN[loc] == LOW[loc]){
        cntSCC++;
        int temp;
        do{
            temp = stk.top();
            stk.pop();
            vis[temp] = 0;
        }while(temp != loc);
    }
}
int main(){
    int nVertex, nEdge;
    while(scanf("%d%d", &nVertex, &nEdge) && nVertex){
        init();
        for(int i = 0; i < nEdge; i++){
            int a, b;
            scanf("%d %d", &a, &b);
            addEdge(a, b);
        }
        for(int i = 1; i <= nVertex; i++)
            if(!DFN[i]) tarjan(i);
        printf("%s\n", cntSCC == 1 ? "Yes" : "No");
    }
    return 0;
}

posted @ 2017-11-11 10:33  1pha  阅读(154)  评论(0编辑  收藏  举报