zoukankan      html  css  js  c++  java
  • 2013 吉林通化邀请赛 D-City 离线型的并查集

    题意:给定n个点和m条边,问你拆掉前i条边后,整个图的连同城市的数量。

    i从1到m。

    思路:计算连通的城市,很容易想到并查集,但是题目里是拆边,所以我们可以反向去做。

    存下拆边的信息,从后往前建边。

    #include <iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    struct node
    {
        int a,b;
    }Q[100005];
    int set[10005];
    int ans[100005];
    void init(int n)
    {
        int i;
        for(i=0;i<n;i++)
        {
            set[i]=i;
        }
    }
    int find(int x)
    {
        int i,j,r = x;
        while (set[r] != r) 
            r = set[r];
        i = x;
        while (i != r)
        {
            j = set[i];
            set[i] = r;
            i = j;
        }
        return r;
    }
    int merge(int x,int y)
    {
        int k,q;
        k=find(x);
        q=find(y);
        if(k==q) return 0;  //合并失败,说明他们本来就连通
        set[q]=k;return 1;  //合并成功,连通区域减1
    }
    int main()
    {
        int n,m,a,b;
        while(~scanf("%d%d",&n,&m))
        {
            int top=0;
            int sum=0;
            for(int i=1;i<=m;i++)
                scanf("%d%d",&a,&b),Q[top].a=a,Q[top++].b=b;
            init(n);
            if(m) ans[sum++]=n;
            int tot=n;
            for(int i=top-1;i>0;i--)
            {
                if(merge(Q[i].a,Q[i].b)) ans[sum++]=--tot;
                    else ans[sum++]=tot;
            }
            for(int i=sum-1;i>=0;i--)
            {
                printf("%d
    ",ans[i]);
            }
        }
        return 0;
    }


  • 相关阅读:
    [Luogu] P1886 滑动窗口
    [Luogu] P1195 口袋的天空
    [Luogu] P1331 海战
    [Luogu] P3952 时间复杂度
    运营活动如何防刷
    考研政治刷题小程序
    考研刷题小程序
    在线答题活动小程序
    知识竞答小程序v2.0
    知识竞答小程序
  • 原文地址:https://www.cnblogs.com/riskyer/p/3279901.html
Copyright © 2011-2022 走看看