UVA - 10765 Doves and bombs(双连通分量)

来源:互联网 发布:js点击图片全屏显示 编辑:程序博客网 时间:2024/06/05 00:56

题目大意:给定一个n个点的连通的无向图,一个点的“鸽子值“定义为将它从图中删去后连通块的个数,求每个点的“鸽子值“

解题思路:双连通分量的裸题。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 10010#define M 100010struct Edge{    int to, next;}E[M];struct Node{    int id, times;}node[N];int head[N], pre[N];int n, m, tot, dfs_clock;bool cmp(const Node &a, const Node &b) {    if (a.times == b.times)        return a.id < b.id;    return a.times > b.times;}int dfs(int u, int  fa) {    int lowu = 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++;            int lowv = dfs(v, u);            lowu = min(lowu, lowv);            if (lowv >= pre[u]) {                node[u].times++;            }        }        else if(pre[v] < pre[u] && v != fa) {            lowu = min(lowu, pre[v]);        }    }    if (fa < 0 && child == 1)        node[u].times = 1;    return lowu;}void solve() {    for (int i = 0; i < n; i++) {        node[i].id = i;        node[i].times = 1;        pre[i] = 0;    }    dfs_clock = 0;    dfs(0, -1);    sort(node, node + n, cmp);    for (int i = 0; i < m; i++)        printf("%d %d\n", node[i].id, node[i].times);    printf("\n");}void AddEdge(int from, int to) {    E[tot].to = to;    E[tot].next = head[from];    head[from] = tot++;}void init() {    memset(head, -1, sizeof(head));    tot = 0;    int u, v;    while (scanf("%d%d", &u, &v) && u >= 0) {        AddEdge(u, v);        AddEdge(v, u);    }}int main() {    while (scanf("%d%d", &n, &m) != EOF && n + m) {        init();        solve();    }    return 0;}
0 0
原创粉丝点击