hdu 4677 并查集+离线+构造 无向图上连续区间的连通块数目

来源:互联网 发布:教育软件下载 编辑:程序博客网 时间:2024/05/20 22:38

把n个点按sqrt(n)的大小划分,第i个区间表示【1,sqrt(n)*i】的连通关系,

离线处理,从后往前边插入边询问,插入u点时,如果[u,v]的v点在区间内,就放在同一集合

有u点的询问对【u,v】时,由于v之前的那个区间的连通关系已经处理好,只须处理v所在区间的起点到v这个区间的连通关系

这个区间不超过sqrt(n)个点,每个点有m/n条边(由于数据是随机产生的),每次复杂度是m/n*sqrt(n),刚好不超,构造奇妙

#include <iostream>#include <cstdio>#include <vector>#include <cmath>#include <cstring>using namespace std;#define N 30050struct Q{    int r,idx;    Q(int _r=0,int _idx=0):r(_r),idx(_idx){}};vector<Q>que[N];vector<int>edge[N];int fa[N][200],scc[200],rr[200];int ta[N],first[N],ans[N];int n,m,tot,every;int find(int i,int pos){    return fa[i][pos]==i?i:fa[i][pos]=find(fa[i][pos],pos);}void init(){    for(int i=0;i<=n;++i)        edge[i].clear(),que[i].clear();    memset(scc,0,sizeof(scc));    every=tot=sqrt(n*1.0);    if(n*n!=tot) tot++;    for(int i=0;;++i)    {        rr[i]=i*every;        if(i*every>=n) break;    }    for(int i=0;i<=tot;++i)        for(int j=0;j<=n;++j)        fa[j][i]=j;    memset(first,-1,sizeof(first));}int main (){    int T;scanf("%d",&T);    for(int kk=1;kk<=T;++kk)    {        scanf("%d%d",&n,&m);        init();        for(int i=1,u,v;i<=m;++i)        {            scanf("%d%d",&u,&v);            if(u==v) continue;            edge[u].push_back(v);            edge[v].push_back(u);        }        int q;scanf("%d",&q);        for(int i=1,u,v;i<=q;++i)        {            scanf("%d%d",&u,&v);            que[u].push_back(Q(v,i));        }        int run_clock=0;        for(int u=n;u>=1;--u)        {            for(int j=1;j<=tot;++j)            {                if(u>rr[j]) continue;                scc[j]++;                int inc=0;                for(int i=0;i<edge[u].size();++i)                {                    int v=edge[u][i];                    if(u<v&&v<=rr[j])                    {                        int u1=find(u,j);                        int v1=find(v,j);                        if(u1!=v1)                        {                            inc++;                            fa[v1][j]=u1;                        }                    }                }                scc[j]-=inc;            }            for(int z=0;z<que[u].size();++z)            {                run_clock++;                int right=que[u][z].r;                int pos;int inc=0;                for(pos=0;pos<tot;++pos)                    if(rr[pos]<right&&right<=rr[pos+1]) break;                for(int i=max(u+1,rr[pos]+1);i<=right;++i)                {                    if(first[i]!=run_clock)                    {                        first[i]=run_clock;                        fa[i][tot+1]=i;                    }                    for(int j=0;j<edge[i].size();++j)                        if(u<=edge[i][j]&&edge[i][j]<i)                        {                            int v1=find(edge[i][j],pos);                            if(first[v1]!=run_clock)                            {                                first[v1]=run_clock;                                fa[v1][tot+1]=v1;                            }                            if(find(i,tot+1)!=find(v1,tot+1))                            {                                fa[find(v1,tot+1)][tot+1]=find(i,tot+1);                                inc++;                            }                        }                }                ans[que[u][z].idx]=scc[pos]+right-max(rr[pos],u-1)-inc;            }        }        printf("Case #%d:\n",kk);        for(int i=1;i<=q;++i)            printf("%d\n",ans[i]);    }    return 0;}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 2岁宝宝胆子小怎么办 坐到小孩的头怎么办 托班幼儿不刷牙怎么办 两岁的宝宝蛀牙怎么办 小孩在学校被打怎么办 油画棒画在墙上怎么办 宝宝把蜡笔吃了怎么办 吃鸡更新了怎么办开始 数字画涂料干了怎么办 广告画颜料干了怎么办 宝宝断奶后瘦了怎么办 腿一个粗一个细怎么办 两条小腿不一样粗怎么办 两岁宝宝坐不了怎么办 q糖孩子吃多了怎么办 q糖孩子吃的太多怎么办 ps图层不能覆盖怎么办 孩子的字写的不好怎么办 孩子爱打人怎么办 6招 一岁宝宝爱打人怎么办 2岁小朋友爱打人怎么办 小朋友爱动手怎么办4岁 5,6岁爱动手打人怎么办 七个月宝宝大便干燥怎么办 两岁宝宝吐奶怎么办 2岁宝宝轻微蛀牙怎么办 2岁宝宝喝水都吐怎么办 2岁宝宝吐的厉害怎么办 两岁宝宝个子矮怎么办 宝宝吐了一天了怎么办 3岁宝宝吃饭呕吐怎么办 3岁宝宝突然呕吐怎么办 11个月婴儿呕吐怎么办 2岁宝宝呕吐是怎么办 2岁宝宝呕吐腹泻怎么办 七个月的宝宝拉肚子怎么办 两岁宝宝玩手机怎么办 5岁宝宝突然口吃怎么办 3岁宝宝突然口吃怎么办 2岁半宝宝结巴怎么办 卤门2岁未闭合怎么办