• HDU


    题意:有N个点M条边的无向图,每次删除一条边直到删完为止,求每一次删边操作之后,连通块的个数。

    M<=1e5,N<=1e4。如果每次删边之后暴力求连通块肯定超时。换个思路,对一个N阶零图,我们用并查集表示每一个点为独立的连通块,然后每次加边后检查边连接的两点是否已在一个连通块中,以此求出每次加边后的连通块个数。

    那么可以把删边的过程倒过来离线处理。

    #include<stdio.h>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    const int maxn = 1e4+5;
    const int INF= 0x3f3f3f3f;
    struct OP{int u,v; }p[maxn*10];
    int fa[maxn];
    int ans[maxn*10];
    void init(int N){ for(int i=0;i<=N;++i) fa[i]=i;}
    inline int Find(int x){return fa[x]==x? x:fa[x]= Find(fa[x]);}
    void Union(int a,int b){
        a = Find(a), b= Find(b);
        if(a!=b) fa[a]= b;
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
             freopen("in.txt","r",stdin);
             freopen("out.txt","w",stdout);
        #endif
        int T,N,M,Q,u,v,tmp,K,cas=1;
        while(scanf("%d%d",&N,&M)==2){
            init(N);
            for(int i=1;i<=M;++i) scanf("%d%d",&p[i].u,&p[i].v);
            int res=N;
            for(int i=M;i>=1;--i){
                int u = p[i].u, v= p[i].v;
                u = Find(u),v = Find(v);
                ans[i] = res;
                if(u!=v){
                    Union(u,v);
                    res--;
                }
            }
            for(int i=1;i<=M;++i) printf("%d
    ",ans[i]);
        }
        return 0;
    }
    为了更好的明天
  • 相关阅读:
    Resharper进阶一
    脚本(js)控制页面输入
    IE图标消失 HTML文件图标变为未知图标的解决方法
    memcache_engine + memcachedb = 高性能分布式内存数据库
    sql 求差值
    MSN、QQ的网页链接代码
    IFrame语法:IFrame实例应用集
    Memcache协议
    Windows下的Memcache安装
    文本框 价格 保留两位小数 讨论
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9414277.html
Copyright © 2020-2023  润新知