zoukankan      html  css  js  c++  java
  • POJ1523 SPF 无向图求割点

    简单的无向图求割点.

    代码如下:

    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #define MAXN 1005
    using namespace std;
    
    int head[MAXN], idx, LIM, dfn[MAXN], low[MAXN], ti;
    int subnet[MAXN];
    bool vis[MAXN];
    
    struct Edge
    {
        int v, next;    
    }e[MAXN*MAXN];
    
    void AddEdge(int x, int v)
    {
        ++idx;
        e[idx].v = v, e[idx].next = head[x];
        head[x] = idx;    
    }
    
    void dfs(int u)
    { // low 值一定是越低越好
        for (int i = head[u]; i != -1; i = e[i].next) {
            if (!vis[e[i].v]) {
                vis[e[i].v] = true;
                dfn[e[i].v] = low[e[i].v] = ++ti;
                dfs(e[i].v); 
                low[u] = min(low[u], low[e[i].v]);
                if (low[e[i].v] == dfn[u]) { // 孩子中不存在抵达上层的其他途径  
                    ++subnet[u];
                }
            }
            else {
                low[u] = min(low[u], dfn[e[i].v]);
            }
        }
    }
    
    void solve()
    {
        bool flag = false;
        memset(vis, false, sizeof (vis));
        memset(subnet, 0, sizeof (subnet));
        subnet[1] = -1;
        vis[1] = true; // 由于图一定是联通的,所以就一定能够找到所有的点
        dfn[1] = low[1] = ++ti;
        dfs(1);
        for (int i = 1; i <= LIM; ++i) {
            if (subnet[i] > 0) {
                printf("  SPF node %d leaves %d subnets\n", i, subnet[i]+1);
                flag = 1;
            }
        }
        if (!flag) {
            puts("  No SPF nodes");    
        }
    }
    
    int main()
    {
        int a, b, ca = 0;
        bool indata = false, first = true;
        LIM = ti = 0, idx = -1;
        memset(head, 0xff, sizeof (head));
        while (1) {
            scanf("%d", &a);
            LIM = max(LIM, a);
            if (!a) {
                if (!indata) break;
                else {
                    if (first) {
                        first = false;    
                    }
                    else {
                        puts("");
                    }
                    indata = false;
                    printf("Network #%d\n", ++ca);
                    solve();
                    LIM = ti = 0, idx = -1; // 一个初始化
                    memset(head, 0xff, sizeof (head));
                    continue;
                }
            }
            indata = true;
            scanf("%d", &b);  // 表示a,b之间有一条无向边
            LIM = max(LIM, b); // 找到最大的顶点编号
            AddEdge(a, b);
            AddEdge(b, a);  // 无向图的双向边 
        }
        return 0;    
    }
  • 相关阅读:
    暑假集训D17总结
    [NOI2014]魔法森林
    暑假集训D16总结
    [繁华模拟赛]Evensgn 剪树枝
    暑假集训D15总结
    Openjudge-计算概论(A)-数组顺序逆放
    Openjudge-计算概论(A)-整数的个数
    Openjudge-计算概论(A)-1的个数
    Openjudge-计算概论(A)-求一元二次方程的根
    Openjudge-计算概论(A)-与7无关的数
  • 原文地址:https://www.cnblogs.com/Lyush/p/2647257.html
Copyright © 2011-2022 走看看