方法一: 16ms
#include<cstdio>
#define maxn 30000
using namespace std;
int tree[maxn+5];//并查集的树
int sum[maxn+5];//嫌疑人数
void init(int n) //并查集的初始化
{
for(int i = 0; i<n; ++i)
{
tree[i] = i;
sum[i] = 1;
}
}
int find(int x)//查找
{
return tree[x]==x?x:tree[x] = find(tree[x]);//路径压缩
}
void merge(int a,int b)
{
int x,y;
x = find(a);
y = find(b);
if(x!=y)
{
tree[x] = y;
sum[y] += sum[x];
}
}
int main()
{
int n,m,k,x,y;
int p1,p2;
while(scanf("%d%d",&n,&m),n)
{
init(n);
while(m--)
{
scanf("%d%d",&k,&p1);
for(int i = 1; i<k; ++i)
{
scanf("%d",&p2);
merge(p1,p2);
}
}
k = find(0);
printf("%d\n",sum[k]);
}
return 0;
}
方法2: 0ms`
#include<cstdio>
#define maxn 30000
using namespace std;
int tree[maxn+5];//并查集的树
int sum[maxn+5];//嫌疑人数
void init(int n) //并查集的初始化
{
for(int i = 0; i<n; ++i)
{
tree[i] = i;
sum[i] = 1;
}
}
int find(int x)//查找
{
return tree[x]==x?x:tree[x] = find(tree[x]);//路径压缩
}
int main()
{
int n,m,k,x,y;
int p1,p2;
while(scanf("%d%d",&n,&m),n)
{
init(n);
while(m--)
{
scanf("%d%d",&k,&p1);
for(int i = 1; i<k; ++i)
{
scanf("%d",&p2);
x = find(p1);
y = find(p2);
if(x!=y)
{
tree[x] = y;
sum[y] += sum[x];
}
}
}
k = find(0);
printf("%d\n",sum[k]);
}
return 0;
}
为什么方法一样但时间有微小差异,两代码唯一不同的是merge函数,0ms并未将merge写在函数外。
这样省去了每次调用函数的时间,可以大致算出每次调用要0.8微秒(16ms/30000)
因此在考虑大数据量时,想加快运行时间,可以考虑将函数写在主函数里,
但不推荐这样,因为会丧失程序的可读性