并查集,找一棵最大的树。因为题目给的是100000条边,点从1~10000000,容易超内存,需要对数据进行处理,网上搜的大多是开了两个10000000的数组,我也没仔细看,不过感觉自己只开一个会节约内存一些。试了一下,是70000+kb与40000+kb的区别。当然,神牛们似乎还有几百kb的处理方法,不过不好搜。这里贴上代码。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define INF 200000000
int head[200001],tail[200001],next[200001],len[200001],flag[10000001],qq[200001];
void subunion(int a,int b)
{
int i,j,k;
len[a]=len[a]+len[b];
next[tail[a]]=b;
tail[a]=tail[b];
i=b;
while(next[i]!=-1)
{
head[i]=a;
i=next[i];
}
head[i]=a;
}
int main()
{
int n,i,j,k,l,m,a,b,t;
while(scanf("%d",&n)!=EOF)
{
t=0;
for(i=1;i<=200000;i++)
{
head[i]=i;
tail[i]=i;
next[i]=-1;
len[i]=1;
}
for(i=1;i<=10000001;i++)
flag[i]=0;
for(i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
if(flag[a]!=0)
a=flag[a];
else
{
t++;
flag[a]=t;
a=t;
}
if(flag[b]!=0)
b=flag[b];
else
{
t++;
flag[b]=t;
b=t;
}
if(head[a]!=head[b])
{
if(len[head[a]]>len[head[b]])
subunion(head[a],head[b]);
else
subunion(head[b],head[a]);
}
}
for(i=1,m=0;i<=200000;i++)
if(len[i]>m)
m=len[i];
printf("%d\n",m);
}
return 0;
}