• Uva 10765 鸽子和炸弹


    题目链接:https://vjudge.net/contest/166461#problem/B

    题意:

    给一个无向图,求每一个点删除后,剩下的连通块的数目;

    分析:

    只有割顶被删掉后,连通分量才会改变,改变多少呢? 就是他这个割顶除 父亲结点,的其他孩子结点(及其子孙结点)是否返回到最早的祖先结点(lowv) <= low[u];再加上原图的连通块;

    WA了很多次,错误地方有两个;

    1、板子抄错了,low 函数没有用子孙结点更新;

    2、即时不是割顶,也要加入结果中,就当是他删掉后,连通分量没有改变;

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 10000+5;
    int n,m;
    
    bool cmp(pair<int,int> a,pair<int,int> b) {
        if(a.second == b.second)
            return a.first < b.first;
        return a.second > b.second;
    }
    
    struct Sol {
        int pre[maxn],iscut[maxn],dfs_clock,bcc_cnt,low[maxn];
        vector<int> G[maxn];
        vector<pair<int,int> > ans;
    
        void init(int n) {
            for(int i=0;i<=n;i++)
                G[i].clear();
            ans.clear();
        }
    
        void AddEdge(int from,int to) {
            G[from].push_back(to);
            G[to].push_back(from);
        }
    
        int dfs(int u,int fa) {
            int lowu = pre[u] = ++dfs_clock;
            int child = 0,num = 0;
            for(int i=0; i<G[u].size(); i++) {
                int v = G[u][i];
                if(v==fa) continue;
                if(!pre[v]) {
                    child++;
                    int lowv = dfs(v,u);
                    lowu = min(lowu,lowv);
                    if(lowv>=pre[u]) {
                        iscut[u] = true;
                        num++;
                    }
                } else if(pre[v]<pre[u]) {
                    lowu = min(lowu,pre[v]);
                }
            }
            if(fa<0&&child==1) {
                iscut[u] = 0;
                num = 0;
            }
            //if(iscut[u])
            ans.push_back(make_pair(u,num));
            low[u] = lowu;
            return lowu;
        }
    
        void find_bcc(int n) {
            memset(pre,0,sizeof(pre));
            memset(iscut,0,sizeof(iscut));
            memset(low,0,sizeof(low));
            dfs_clock = bcc_cnt = 0;
            for(int i=0; i<n; i++)
                if(!pre[i]) {
                    bcc_cnt++;
                    dfs(i,-1);
                }
        }
    
        void print_ans() {
            sort(ans.begin(),ans.end(),cmp);
            for(int i=0; i<m; i++)
                printf("%d %d
    ",ans[i].first,ans[i].second+bcc_cnt);
            puts("");
        }
    } sol;
    
    int main() {
        while(scanf("%d%d",&n,&m),n) {
            sol.init(n);
            int u,v;
            while(true) {
                scanf("%d%d",&u,&v);
                if(u==-1) break;
                sol.AddEdge(u,v);
            }
            sol.find_bcc(n);
            sol.print_ans();
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    01uni-app的创建运行在不同端上的配置 以及tarBar的配置
    js循环之map在工作中的使用
    GPTL L3-003 社交集群(并查集)
    GPLT L2-024 部落 (并查集)
    GPLT L2-010 排座位 (并查集)
    GPLT L2-007 家庭房产 (并查集)
    Codeforces Round #533 (Div. 2) D. Kilani and the Game(BFS)
    Codeforces Round #533 (Div. 2) C. Ayoub and Lost Array(递推)
    Codeforces Round #533 (Div. 2) B. Zuhair and Strings(字符串)
    Codeforces Round #533 (Div. 2) A. Salem and Sticks(枚举)
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6952476.html
Copyright © 2020-2023  润新知