UVA10765-Doves and bombs(BCC)

来源:互联网 发布:cs1.6弹道优化 编辑:程序博客网 时间:2024/06/13 08:28

题目链接


题意:给定一个n个点的连通的无向图,一个点的“鸽子值”定义为将它从图中删去后连通块的个数。求“鸽子值”按降序排列的前m个。

思路:其实题目就是要用来寻找割顶,我们只需找出割顶,然后记录这个割顶属于几个不同连通分量的公共点,不是割点的,去掉之后,图的连通块数为1。

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <stack>#include <algorithm>using namespace std;const int MAXN = 10005;struct node{    int id, val;}b[MAXN];int n, m;int pre[MAXN], low[MAXN], dfs_clock;vector<int> g[MAXN];void init() {    for (int i = 0; i < n; i++)         g[i].clear();    for (int i = 0; i < n; i++) {        b[i].id = i;         b[i].val = 1;    }     }bool cmp(node a, node b) {    if (a.val == b.val)        return a.id < b.id;    return a.val > b.val;}int dfs(int u, int fa) {    int lowu = pre[u] = ++dfs_clock;    int child = 0;    for (int i = 0; i < g[u].size(); i++) {        int v = g[u][i];         if (!pre[v]) {            child++;            int lowv = dfs(v, u);            lowu = min(lowu, lowv);            if (lowv >= pre[u]) {                b[u].val++;            }        }         else if (pre[v] < pre[u] && v != fa) {            lowu = min(lowu, pre[v]);        }    }    if (fa < 0 && child == 1) b[u].val = 1;    low[u] = lowu;    return lowu;}void find_bcc(int n) {    memset(pre, 0, sizeof(pre));    memset(low, 0, sizeof(low));    dfs_clock = 0;    for (int i = 0; i < n; i++)        if (!pre[i])            dfs(i, -1);}int main() {    while (scanf("%d%d", &n, &m)) {        if (n == 0 && m == 0)            break;        init();        int u, v;        while (scanf("%d%d", &u, &v)) {            if (u == -1 && v == -1)                break;            g[u].push_back(v);            g[v].push_back(u);         }        find_bcc(n);        sort(b, b + n, cmp);        for (int i = 0; i < m; i++)            printf("%d %d\n", b[i].id, b[i].val);        puts("");    }         return 0;}


0 0
原创粉丝点击