设为首页 加入收藏

TOP

poj 1523 SPF(tarjan求割点)
2014-11-23 21:46:39 来源: 作者: 【 】 浏览:11
Tags:poj 1523 SPF tarjan
题意
给一个连通的无向图,求这个图的所有割点,并且输出各个割点和相连的边去掉之后,会变成几个连通分量
思路
用tarjan求割点的基础题,要求对tarjan算法的原理真正搞懂,这题就水了。
代码
/**=====================================================
 *   This is a solution for ACM/ICPC problem
 *
 *   @source      : poj-1523 SPF
 *   @description : 图的连通性-tarjan求割点
 *   @author      : shuangde
 *   @blog        : blog.csdn.net/shuangde800
 *   @email       : zengshuangde@gmail.com
 *   Copyright (C) 2013/09/04 20:15 All rights reserved. 
 *======================================================*/

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

typedef long long int64;
const int INF = 0x3f3f3f3f;

const int MAXN = 1010;
int n;
bool ok;
int cnt[MAXN];

namespace Adj {
    int size, head[MAXN];
    struct Node {
        int v, next; 
    }E[MAXN*2];
    inline void initAdj() {
        size = 0;
        memset(head, -1, sizeof(head));
    } 
    inline void addEdge (int u, int v) {
        E[size].v = v;
        E[size].next = head[u];
        head[u] = size++;
    }
}
using namespace Adj;


namespace Tarjan {
    bool vis[MAXN];
    int dfn[MAXN], low[MAXN], idx;

    inline void initTarjan() {
        idx = 1; 
        memset(vis, 0, sizeof(vis));
        memset(dfn, 0, sizeof(dfn));
        memset(low, 0, sizeof(low));
    }

    void tarjan(int u) {

        vis[u] = true;
        dfn[u] = low[u] = idx++;

        for (int e = head[u]; e != -1; e = E[e].next) {
            int v = E[e].v;
            if (vis[v]) {
                low[u] = min(low[u], dfn[v]);  
            } else {
                tarjan(v);
                low[u] = min(low[u], low[v]);
                if (u == 1) { 
                    ++cnt[u];
                    if (cnt[u] == 2) ok = true;
                }
                else if (low[v] >= dfn[u]) {
                    ok = true;
                    ++cnt[u];
                }
            }
        }
    }
}
using namespace Tarjan;

int main(){

    int cas = 1;
    int u, v;
    while (~scanf("%d", &u) && u) {

        scanf("%d", &v);
        initAdj();
        n = 0;
        n = max(n, max(u, v));
        addEdge(u, v); 
        addEdge(v, u);

        while (~scanf("%d", &u) && u) {
            scanf("%d", &v);
            n = max(n, max(u, v));
            addEdge(u, v);
            addEdge(v, u);
        }

        if (cas != 1) puts("");
        printf("Network #%d\n", cas++);

        memset(cnt, 0, sizeof(cnt));
        ok = false;
        initTarjan();
        tarjan(1);

        if (!ok) puts("  No SPF nodes");
        else {
            if (cnt[1] > 1)
                printf("  SPF node %d leaves %d subnets\n", 1, cnt[1]);
            for (int i = 2; i <= n; ++i) {
                if (cnt[i])
                    printf("  SPF node %d leaves %d subnets\n", i, cnt[i] + 1);
            }
        }
    }

    return 0;
}


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇二叉排序算法(稳定 最小交换次数.. 下一篇POJ 2828 Buy Tickets

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·一篇说人话的文章, (2025-12-27 07:50:09)
·Python Web框架哪家 (2025-12-27 07:50:06)
·基于Python的数据分 (2025-12-27 07:50:03)
·深入理解 Java 集合 (2025-12-27 07:22:48)
·Java集合框架全面解 (2025-12-27 07:22:45)