POJ 3065 Stargates

数据量比较大的并查集

一开始一直RE,提取字符串中的整数时出错了,换种方法就AC了

思路:路径压缩的并查集

一个小优化(766ms)挤进第一版:合并集合的时候始终以把较大的数的集合并到较小的数的集合

#include<cstdio>
#include<ctype.h>
#include<algorithm>
#define MAXN 6000010
using namespace std;

int set[MAXN];

int Find(int x)
{
    if(x==set[x])
        return x;
    set[x]=Find(set[x]);
    return set[x];
}

void Connect(int a,int b)
{
    int x=Find(a);
    int y=Find(b);
    if(x>y)
        swap(x,y);
    set[y]=x;
}

int getNum(char *s)
{
    int i,k=0;
    for(i=1;s[i]!='\0';i++)
        if(s[i]!=' '&&s[i-1]==' ')
            k++;
    return k;
}

bool Query(int a,int b)
{
    int x=Find(a);
    int y=Find(b);
    return x==y;
}

int main()
{
    char s[100];
    int i,j,k,n,l,r,v,w;
    int src, dst, nnn, dststep, srcstep;
    char cmd;
    for(;gets(s);)
    {
        cmd=tolower(s[0]);
        if(cmd=='d')
        {
            sscanf(s,"%*s %d",&n);
            for(i=0;i<=n;i++)
                set[i]=i;
        }
        else
        {
            k=getNum(s);
            nnn=dststep=1;srcstep=0;
            if(k==2) sscanf(s,"%*s %d %d",&src,&dst);
            else if(k==3) sscanf(s,"%*s %d %d %d",&src,&dst,&nnn);
            else if(k==4) sscanf(s,"%*s %d %d %d %d",&src,&dst,&nnn,&dststep);
            else sscanf(s,"%*s %d %d %d %d %d",&src,&dst,&nnn,&dststep,&srcstep);
            if(cmd=='c')
            {
                if(dststep==srcstep&&!srcstep)
                    nnn=1;
                for(i=0,v=src,w=dst;i<nnn;i++,v+=srcstep,w+=dststep)
                    Connect(v,w);
            }
            else
            {
                l=r=0;
                for(i=0,v=src,w=dst;i<nnn;i++,v+=srcstep,w+=dststep)
                    Query(v,w)?l++:r++;
                printf("%d - %d\n",l,r);
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xchaos/p/2528996.html