zoukankan      html  css  js  c++  java
  • BZOJ-3237: [Ahoi2013]连通图

    BZOJ-3237: [Ahoi2013]连通图

    标签(空格分隔): OI-BZOJ OI-整体二分 OI-并查集


    Time Limit: 20 Sec
    Memory Limit: 512 MB


    Description

    此处输入图片的描述

    Input

    此处输入图片的描述

    Output

    此处输入图片的描述

    Sample Input

    4 5

    1 2

    2 3

    3 4

    4 1

    2 4

    3

    1 5

    2 2 3

    2 1 2

    Sample Output

    Connected

    Disconnected

    Connected
    HINT

    N<=100000 M<=200000 K<=100000


    Solution####

    这图上数据范围不对坑爹呢。。。
    整体二分。对询问二分。求询问[l,l]的答案的时候,需要把未在[l,l]间
    出现的边缩成一个强联通分量,判断询问l的边是否在一个强联通分量。
    在整体二分中处理方法为:对于当前区间[l,r],把在[mid+1,r]出现且
    未在[l,mid]中出现的边缩起来,对[l,mid]递归处理;同理,把在[l,mid]
    出现且未在[mid+1,r]中出现的边缩起来,对[mid+1,r]递归处理。
    开始的时候把未被询问到的边缩起来。


    Code####

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    #include<bitset>
    #include<vector>
    using namespace std;
    #define PA pair<int,int>
    int read()
    {
     	int s=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+ch-'0';ch=getchar();}
    	return s*f;
    }
    //smile please
    int n,m,Q;
    int u[200005],v[200005];
    struct que
    {
    	int N,h;
    	int e[5];
    }q[200005];
    bool ans[200005];
    int f[100005],s1[5000005],top=1;
    int gf(int x)
    {
    	if(f[x]==x)return x;
    	s1[top++]=x;s1[top++]=f[x];
    	return f[x]=gf(f[x]);
    }
    int p[200005],dd;
    void mer(int u,int v)
    {
    	if(gf(u)!=gf(v))
    	  {s1[top++]=f[v];s1[top++]=f[f[v]];
    	   f[f[v]]=f[u];
     	  }
    }
    void solve(int l,int r)
    {
    	int time=top,mid=l+r>>1;
    	if(l==r)
    	   {int p=1;
    	    for(int j=q[l].N,*k=q[l].e;j&&p;j--,k++)
    	        if(gf(u[*k])!=gf(v[*k]))
    	          p=0;
    		ans[q[l].h]=p;
    		while(top!=time)
    	  	  f[s1[top-2]]=s1[top-1],top-=2;
    		return;
    	   }
    	dd++;
    	for(int i=l;i<=mid;i++)
    	    for(int j=q[i].N,*k=q[i].e;j;j--,k++)
    	        p[*k]=dd;
    	for(int i=mid+1;i<=r;i++)
    	    for(int j=q[i].N,*k=q[i].e;j;j--,k++)
    	        if(p[*k]!=dd)
    	          mer(u[*k],v[*k]);
    	solve(l,mid);
    	while(top!=time)
    	  f[s1[top-2]]=s1[top-1],top-=2;
    	
    	dd++;
    	for(int i=mid+1;i<=r;i++)
    	    for(int j=q[i].N,*k=q[i].e;j;j--,k++)
    	        p[*k]=dd;
    	for(int i=l;i<=mid;i++)
    	    for(int j=q[i].N,*k=q[i].e;j;j--,k++)
    	        if(p[*k]!=dd)
    	          mer(u[*k],v[*k]);
    	solve(mid+1,r);
    	while(top!=time)
    	    f[s1[top-2]]=s1[top-1],top-=2;
    }
    int main()
    {
     	//freopen(".in","r",stdin);
    	//freopen(".out","w",stdout);
    	n=read(),m=read();
    	for(int i=1;i<=m;i++)
    	    u[i]=read(),v[i]=read();
    	for(int i=1;i<=n;i++)
    	    f[i]=i;
    	Q=read();
    	for(int i=1;i<=Q;i++)
    	   {q[i].N=read();q[i].h=i;
    	    for(int j=0;j<q[i].N;j++)
    	        q[i].e[j]=read();
    	   }
    	dd++;
    	for(int i=1;i<=Q;i++)
    	    for(int j=q[i].N,*k=q[i].e;j;j--,k++)
    	        p[*k]=dd;
    	for(int i=1;i<=m;i++)
    	    if(p[i]!=dd)
    	      mer(u[i],v[i]);
    	solve(1,Q);
    	for(int i=1;i<=Q;i++)
    	    puts(ans[i]?"Connected":"Disconnected");
    	//fclose(stdin);
    	//fclose(stdout);
    	return 0;
    }
    
    
  • 相关阅读:
    利用...来字符检測(swift)
    iOS开发中WebP格式的64位支持处理
    Hadoop与分布式开发
    Lua代码解析-写给C和C++开发人员
    logback使用
    【mysql】更新“”空字符串为NULL
    【java】代码优化点
    【java】java获取对象属性类型、属性名称、属性值
    【mybatis】mybatis中放置IN查询拼接sql过长,IN查询进行分批次查询的处理
    【java】java中替换中括号[ ]操作
  • 原文地址:https://www.cnblogs.com/wuyuhan/p/5276370.html
Copyright © 2011-2022 走看看