typedef struct edge
{
int u;
int v;
int w;
}edge;
edge e[10];
int n,m;
int f[7] = {0},sum = 0,count = 0;
void quicksort(int left,int right)
{
int i,j;
edge t;
if(left>right)
return;
i = left;
j = right;
while(i != j)
{
//从右边开始找比基准值小的元素
while(e[j].w>=e[left].w&&i<j)
j--;
//从左边找比基准值大的元素
while(e[i].w<=e[left].w&&i<j)
i++;
if(i < j)//交换
{
t = e[i];
e[i] = e[j];
e[j] = t;
}
}
//将基准数归位 (放到最后应该在的位置),将left的和i互换m;
t = e[left];
e[left] = e[i];
e[i] = t;
quicksort(left,i-1);
quicksort(i+1,right);
return;
}
int getf(int v)
{
if(f[v] == v)
return v;
else
{
f[v] = getf(f[v]);
return f[v];
}
}
int merge(int u,int v)
{
int t1,t2;
t1 = getf(u);
t2 = getf(v);
if(t1 != t2);//判断两个节点是否在同一个集合中 ,即是否为同一个祖先
{
f[t2] = t1;
return 1;
//靠左原则,左边的变成右边的boss
}
return 0;
}
int main ()
{
int i,j;
scanf("%d %d",&n,&m);
for(i=1;i <= m;i++)
scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);
quicksort(1,m);
for(i = 1;i <= n;i++)
f[i]= i;
for(i = 1;i <= m;i++)
{
if(merge(e[i].u,e[i].v) > 0)
{
count++;
sum += e[i].w;
printf("%d %d\n",e[i].u,e[i].v);
for(j = 1;j <= 6;j++)
printf("%d ",f[j]);
printf("\n");
}
if(count == n-1)
break;
}
printf("%d",sum);
return 0;
}
6 9
2 4 11
3 5 13
4 6 3
5 6 4
2 3 6
4 5 7
1 2 1
3 4 9
1 3 2
这里是测试数据
正确结果应该是19
这个程序输出结果是16
如果只是普通的竞赛或算法设计,并查集建议还是写常规版本吧。效率也挺快的,简单易懂还好写。
(不是广告)如何实现,可以去我的博客https://www.cnblogs.com/wondering-world/p/12713965.html或者洛谷看看呗。
你好,我刚刚修改了一下你的代码,发现应该是排序的时候出现了问题。在我定义了cmp函数,用sort对edge进行排序之后,就不会出现错误。
同时也完全不需要写merge函数,因为本来就是一个很简短的小判断,何必多写一个函数增加代码长度呢?完全可以按照注释中的来
@雪之下,树之旁: 谢谢,我去试试,我这刚学啊😂
@雪之下,树之旁: 你好,我看了下,排序结果没问题啊
1 2
1 3
4 6
5 6
2 3
4 5
3 4
2 4
3 5
@FutureWorld: 那你看看我注释的那一段和你原来的差别。因为这一段我删掉自己重打过。
@雪之下,树之旁: 看过,你这个没有对f[i]的 值进行更新吧,
1 2
1 3
4 6
5 6
2 3
4 5
3 4
2 4
3 5//排序结果
1 2
1 1 3 4 5 6
1 3
1 1 1 4 5 6
4 6
1 1 1 4 5 4
5 6
1 1 1 5 5 4
2 3//按程序应该不会执行这一步,会跳过
1 1 1 5 5 4
16//结果