POJ - 1523 SPF(割点)

题目大意:给出一张图,问去割点后,连通分量的个数有多少

解题思路:割点的水题,套模版就可以
不得不吐槽一下输入。。

#include <cstdio>
#include <cstring>

#define min(a,b) ((a)<(b)?(a):(b))
#define N 1010
#define M 2000010

struct Edge{
    int to, next;
}E[M];

int head[N], num[N], pre[N], lowlink[N];
int tot, dfs_clock, root;
bool iscut[N];

void dfs(int u, int fa) {
    lowlink[u] = pre[u] = ++dfs_clock;
    int child = 0;
    for (int i = head[u]; i != -1; i = E[i].next) {
        int v = E[i].to;
        if (!pre[v]) {
            child++;
            dfs(v, u);
            lowlink[u] = min(lowlink[u],lowlink[v]);
            if ((u == root && child > 1) || (u != root && pre[u] <= lowlink[v])) {
                num[u]++;
            }
        }
        else if (v != fa)  {
            lowlink[u] = min(lowlink[u], pre[v]);
        }
    }
}

int cas = 1;
void solve() {
    memset(pre, 0, sizeof(pre));
    memset(num, 0, sizeof(num));
    dfs_clock = 0;

    for (int i = 1; i <= 1000; i++) {
        if (!pre[i] && head[i] != -1) {
            root = i;
            dfs(i,-1);
        }
    }
    printf("Network #%d\n", cas++);
    bool flag = false;
    for (int i = 1; i <= 1000; i++)
        if (num[i]) {
            printf("  SPF node %d leaves %d subnets\n", i, num[i] + 1);
            flag = true;
        }
    if (!flag) {
        printf("  No SPF nodes\n");
    }
}

void AddEdge(int u, int v) {
    E[tot].to = v; E[tot].next = head[u]; head[u] = tot++;
    u = u ^ v; v = u ^ v; u = u ^ v;
    E[tot].to = v; E[tot].next = head[u]; head[u] = tot++;
}

int main() {
    int a, b;
    bool flag = false;
    while (scanf("%d", &a) != EOF && a) {
        if (flag)
            printf("\n");
        flag = true;
        memset(head, -1, sizeof(head));
        tot = 0;
        scanf("%d", &b);
        AddEdge(a,b);
        while (scanf("%d", &a) && a) {
            scanf("%d", &b);
            AddEdge(a,b);
        }
        solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值