HDU 1269 迷宫城堡(强连通图)

题目链接

解题思路

  题目的意思很明显,就是让判断一个图是不是一个连通图。这里测试一下\(tarjan\)算法求强连通分量的模板。

代码

const int maxn = 1e4+10;
const int maxm = 1e5+10;
struct {
    int to, nex;
} e[maxm<<1];
int h[maxn], ecnt;
void ae(int u, int v) {
    e[ecnt].to = v;
    e[ecnt].nex = h[u];
    h[u] = ecnt++;
}
int dfn[maxn], dfncnt; //访问过的点&&编号
int low[maxn]; //可以指向的最小编号的点
int sk[maxn], tp; //模拟栈
int scc[maxn], sc; //强连通分量&&编号
int sz[maxn]; //强连通分量的大小
void tarjan(int u) {
    sk[++tp] = u;
    low[u] = dfn[u] = ++dfncnt; 
    for (int i = h[u]; i; i = e[i].nex) {
        int v = e[i].to;
        if (!dfn[v]) { //未访问过
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if (!scc[v]) //访问过并且还在栈中
            low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u]==low[u]) {
        ++sc;
        while(true) { //给同一个联通分量内的点标记&&计算大小
            int v = sk[tp--];
            scc[v] = sc;
            ++sz[sc];
            if (u==v) break;
        }
    }
    return;
}
int main() {
    int n, m, u, v;
    while(~scanf("%d%d", &n, &m) && (n||m)) {
        zero(dfn); zero(low); zero(scc); zero(sz); zero(h);
        dfncnt = tp = sc = 0; ecnt = 1;
        for (int i = 0; i<m; ++i) {
            scanf("%d%d", &u, &v);
            ae(u, v);
        }
        for (int i = 1; i<=n; ++i)
            if (!dfn[i]) tarjan(i);
        printf("%s\n", sc==1?"Yes":"No");
    }
    return 0;
}
posted @ 2020-05-12 16:37  shuitiangong  阅读(141)  评论(0编辑  收藏  举报