HDU 4496 D-City (并查集)

来源:互联网 发布:运营淘宝店 编辑:程序博客网 时间:2024/05/07 03:30

题意:有n个城市,m条路,首先m条路都连上,接着输出m行,第i行代表删除前i行的得到的连通块个数

题解:正难则反,我们反向考虑使用并查集添边。首先每个点都没有相连,接着倒着来边添加边计算,当两个点父节点相同时连通块不变,否则-1

#include<set>#include<map>#include<queue>#include<stack>#include<cmath>#include<vector>#include<string>#include<cstdio>#include<cstring>#include<stdlib.h>#include<iostream>#include<algorithm>using namespace std;#define eps 1E-8/*注意可能会有输出-0.000*/#define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型#define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0#define mul(a,b) (a<<b)#define dir(a,b) (a>>b)typedef long long ll;typedef unsigned long long ull;const int Inf=1<<28;const double Pi=acos(-1.0);const int Mod=1e9+7;const int Max=10010;int fat[Max];struct node{    int xx1,yy1;}lin[Max<<4];int ans[Max<<4];void Init(int n){    for(int i=0;i<=n;i++)        fat[i]=i;    return;}int Find(int x){    if(x==fat[x])        return fat[x];    return fat[x]=Find(fat[x]);}int Union(int x,int y){    int x1=Find(x);    int y1=Find(y);    if(x1==y1)        return 0;        fat[x1]=y1;    return 1;}int main(){    int n,m;    while(~scanf("%d %d",&n,&m))    {        Init(n);        for(int i=0;i<m;i++)            scanf("%d %d",&lin[i].xx1,&lin[i].yy1);        int num=n;        for(int i=m-1;i>=0;i--)//离线倒序        {            ans[i]=num;            num-=Union(lin[i].xx1,lin[i].yy1);        }        for(int i=0;i<m;i++)        printf("%d\n",ans[i]);    }    return 0;}
0 0
原创粉丝点击