POJ-1523 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;    

}

你可能感兴趣的:(poj)