bzoj3563: DZY Loves Chinese

口口相传的搞笑题啊啊啊啊啊

通过他的输入就可以得出第i个询问前联通的个数。。

然后只需要求最后一个就行了。。。

PS:肉老师告诉这题读入有毒。。自己看看吧

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

struct node
{
    int x,y;
}a[510000];
int gt[510000];
bool v[510000];
int fa[510000];
int findfa(int x)
{
    if(fa[x]==x)return x;
    fa[x]=findfa(fa[x]);return fa[x];
}
char ss[21110000];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)scanf("%d%d",&a[i].x,&a[i].y);
    
    int Q;
    scanf("%d\n",&Q);
    for(int T=1;T<=Q;T++)
    {
        gets(ss+1);int len=strlen(ss+1);
        
        int sum=0;
        for(int i=1;i<=len;i++)
            if(ss[i]==' ')sum++;
            
        int k=0;
        for(int i=1;i<=len;i++)
        {
            if('0'<=ss[i]&&ss[i]<='9')k=k*10+ss[i]-'0';
            else break;
        }
        gt[T]=k^sum;
    }
    for(int T=2;T<=Q;T++)
    {
        if(gt[T]-gt[T-1]==1)printf("Connected\n");
        else printf("Disconnected\n");
    }
    
    int k=0,tp,len=strlen(ss+1);
    for(int i=1;i<=len;i++)
    {
        if('0'<=ss[i]&&ss[i]<='9')k=k*10+ss[i]-'0';
        else {k^=gt[Q];tp=i+1;break;}
    }
    memset(v,false,sizeof(v));
    for(int i=1;i<=k;i++)
    {
        int x=0,j=tp;
        while(ss[j]>='0'&&ss[j]<='9')x=x*10+ss[j]-'0',j++;
        tp=j+1;x^=gt[Q];
        v[x]=true;
    }
    int cnt=n;
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=m;i++)
        if(v[i]==false)
        {
            int fx=findfa(a[i].x),fy=findfa(a[i].y);
            if(fx!=fy)
            {
                fa[fx]=fy;
                cnt--;if(cnt==1)break;
            }
        }
    if(cnt==1)printf("Connected\n");
    else printf("Disconnected\n");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/AKCqhzdy/p/8921449.html