hdu 4496 并查集

来源:互联网 发布:最小文章cms 编辑:程序博客网 时间:2024/06/05 16:11

这道题是最容易一下ac的,结果我却写并查集的时候写错了,wa的次数我都不想说了啊!!!!

题目中要求去边求连通的个数,可以逆向思维,不断的从后向前加边,然后就是刚开始的分量为n,然后不断的合并数,在同一个树上的时候则连通分量的个数不变,否则减一。。。

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<cmath>#include<algorithm>#include<queue>#include<stack>#include<vector>#include<climits>#include<map>using namespace std;#define rep(i,n) for(int i=0; i<n; i++)#define repf(i,n,m) for(int i=(n); i<=(m); ++i)#define repd(i,n,m) for(int i=(n); i>=(m); --i) #define ll long long#define arc(a) ((a)*(a))#define inf 100000#define exp 0.000001#define N 1000010#define M 100050struct node{    int x,y;};node a[N];int pre[N];int ans[N];int n,m;int fa(int x){    if(pre[x]!=x)        pre[x]=fa(pre[x]);    return pre[x];}void solve(){    rep(i,n+10) pre[i]=i;    memset(ans,0,sizeof(ans));    ans[m]=n;    repd(i,m-1,1)    {        int x=a[i].x,y=a[i].y;        int mm=fa(x),nn=fa(y);         if(mm==nn)                ans[i]=ans[i+1];        else            pre[mm]=pre[nn],                ans[i]=ans[i+1]-1;    }    repf(i,1,m)         printf("%d\n",ans[i]);}int main(){    while(cin>>n>>m)   {   rep(i,m) scanf("%d%d",&a[i].x,&a[i].y);   solve();   }   return 0;}


原创粉丝点击