首页 新闻 赞助 找找看

并查集解决最小生成树问题,求帮助

0
悬赏园豆:10 [已解决问题] 解决于 2020-04-19 16:54

include <stdio.h>

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

木有呂朋友的主页 木有呂朋友 | 初学一级 | 园豆:99
提问于:2020-04-16 16:23
< >
分享
最佳答案
0

如果只是普通的竞赛或算法设计,并查集建议还是写常规版本吧。效率也挺快的,简单易懂还好写。
(不是广告)如何实现,可以去我的博客https://www.cnblogs.com/wondering-world/p/12713965.html或者洛谷看看呗。

收获园豆:10
雪之下,树之旁 | 初学一级 |园豆:177 | 2020-04-16 16:57

你好,我刚刚修改了一下你的代码,发现应该是排序的时候出现了问题。在我定义了cmp函数,用sort对edge进行排序之后,就不会出现错误。

同时也完全不需要写merge函数,因为本来就是一个很简短的小判断,何必多写一个函数增加代码长度呢?完全可以按照注释中的来

雪之下,树之旁 | 园豆:177 (初学一级) | 2020-04-16 17:24

@雪之下,树之旁: 谢谢,我去试试,我这刚学啊😂

木有呂朋友 | 园豆:99 (初学一级) | 2020-04-16 19:01

@雪之下,树之旁: 你好,我看了下,排序结果没问题啊
1 2
1 3
4 6
5 6
2 3
4 5
3 4
2 4
3 5

木有呂朋友 | 园豆:99 (初学一级) | 2020-04-16 20:37

@FutureWorld: 那你看看我注释的那一段和你原来的差别。因为这一段我删掉自己重打过。

雪之下,树之旁 | 园豆:177 (初学一级) | 2020-04-16 20:39

@雪之下,树之旁: 看过,你这个没有对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//结果

木有呂朋友 | 园豆:99 (初学一级) | 2020-04-16 20:58
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册