HDU 3371 Connect the Cities 最小生成树(和关于sort和qsort的一些小发现)

时间:2021-06-13 21:59:20

解题报告:有n个点,然后有m条可以添加的边,然后有一个k输入,表示一开始已经有k个集合的点,每个集合的点表示现在已经是连通的了。

还是用并查集加克鲁斯卡尔。只是在输入已经连通的集合的时候,通过并查集将该集合的点标记到一起,然后剩下的就可以当成是普通的最小生成树来做了题目代码如下:

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
using namespace std; struct node
{
int front ,rear,cost;
}rode[];
int pre[];
int find(int n)
{
return pre[n] == n? n:pre[n] = find(pre[n]);
}
int cmp(const void *a,const void *b)
{
return (*(node*)a).cost <= (*(node*)b).cost? -:;
}
int judge(int n)
{
for(int i = ;i <= n;++i)
if(find() != find(i))
return ;
return ;
} int main()
{
int T;
int ci,s,d;
scanf("%d",&T);
while(T--)
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i = ;i <= m;++i)
scanf("%d%d%d",&rode[i].front,&rode[i].rear,&rode[i].cost);
qsort(rode+,m,sizeof(node),cmp);
for(int i = ;i <= n;++i)
pre[i] = i;
while(k--)
{
scanf("%d%d",&ci,&s);
ci--;
while(ci--)
{
scanf("%d",&d);
pre[find(s)] = find(d);
}
}
int ans = ;
for(int i = ;i <= m;++i)
{
int temp1 = find(rode[i].front);
int temp2 = find(rode[i].rear);
if(temp1 != temp2)
{
ans += rode[i].cost;
pre[temp1] = temp2;
}
}
printf(judge(n)? "%d\n":"-1\n",ans);
}
return ;
}

不过,我过这道题的时候发现一个小问题,就是在排序的时候用sort总会T,但是发现改成qsort之后,比原来快了很多,然后就A了。经过一些测试发现,qsort在数据量比较大的时候要比sort更快,而且数据量越大,差别越大,下面再附上测试用的代码:

 #include<cstdio>
#include<iostream>
#include<algorithm>
#include<time.h>
using namespace std; const int maxn = ; int que[maxn]; int cmp(const void *a,const void *b)
{
return (*(int*)a) <= (*(int*)b)? -:;
}
bool comp(int a,int b)
{
return a <= b;
}
int main()
{
for(int i = maxn - ;i >=;--i)
que[i] = i;
int s = clock();
qsort(que,maxn,sizeof(int),cmp);
int e = clock();
printf("t_qsort = %d\n",e - s);
s = clock();
sort(que,que+maxn,comp);
e = clock();
printf("t_sort = %d\n",e - s);
return ;
}