zoukankan      html  css  js  c++  java
  • 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
    ", sc==1?"Yes":"No");
        }
        return 0;
    }
    
  • 相关阅读:
    C++ 17
    C++ 11
    mysql统计某一个数据库中有几张表
    poj2636---Electrical Outlets(插线板)
    poj2608---几个字母映射到同一个数字
    poj2583---Series Determination
    poj2578---三个数中找出第一个大于168的
    poj2521---lose money
    poj2538---字符匹配(映射)
    poj2509---抽k根烟就换一支,求能抽烟的总数
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12877089.html
Copyright © 2011-2022 走看看