HDU - 4496 City (逆向并查集)

Posted xiuwenli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 4496 City (逆向并查集)相关的知识,希望对你有一定的参考价值。

题意:有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;
}

 

以上是关于HDU - 4496 City (逆向并查集)的主要内容,如果未能解决你的问题,请参考以下文章

hdu 4496 并查集 反向并查集 水题 D-City

HDU 4496 并查集

HDU 4496 并查集

ZOJ 3261 Connections in Galaxy War (逆向+带权并查集)

[HDU 7136] Jumping Monkey | 并查集 | 逆向思维

hdu-4496-D-City