关于最小生成树现在我只看了克鲁斯卡尔算法,prim算法还没来得及看,先练练kruskal吧,ta用的都是这两个方法写的,确实比较牛,我也正在努力超越,这道题就是纯粹的最小生成树,白书上说kruskal算法基本上都是和并查集一起用的,这样实现起来更高效,确实不错。
关于刷题,我似乎有点感触了,我觉得不能一味的刷题,用题目的数量来满足自己,其实学习一个知识点,我们要理解为什么要用到它,用它来干什么,它可以帮助我们解决什么样的问题,所以,以后学习算法就要多思考,多总结,不能简简单单为了AC,话说最近一直都是提交一次就过了诶,哈哈,继续练,加油
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct
{
int i,j;//用来存放节点两端的序号
int len;//len存放权值
}node;
int p1[100];
node map[100];
int find(int x)
{
return p1[x]==x? x:p1[x]=find(p1[x]);//用并查集实现判断连个节点是否在同一个连通分量里面,即判断是不是会构成一个环
}
int cmp(const void *a,const void *b)
{
return ((node *)a)->len-((node *)b)->len;//对结构体数组进行排序,放在一个结构体数组就可以实现由一个变量决定的序列
}
int main()
{
int n,i,j,k;
char x;
int p,q,z,y,ans,sum;
while(scanf("%d",&n),n!=0)
{
sum=0;
p1[1]=0;
for(i=0;i<n;i++)
p1[i]=i;//并查集的初始化
ans=0;
for(i=0;i<n-1;i++)
{
getchar();
scanf("%c",&x);
p=x-'A';
scanf("%d",&y);
while(y--)
{
getchar();
scanf("%c",&x);
q=x-'A';
scanf("%d",&z);
map[ans].i=p;
map[ans].j=q;
map[ans++].len=z;
}
}
qsort(map,ans,sizeof(map[0]),cmp);
for(i=0;i<ans;i++)
{
int x1=find(map[i].i);//找到map[i].i的代表节点
int y1=find(map[i].j);//找到map[i].j的代表节点
if(x1!=y1)
{
sum+=map[i].len;
p1[x1]=y1;//把他们放到同一个连通分量里面
}
}
printf("%d\n",sum);
}
}
又学习了Prim算法写了一遍,感觉很好哦,又学会了一种算法,又是一遍AC, 嘿嘿,是看ta的博客学习的,当然比较好过咯,接下来继续练习最小生成树kruskal算法和Prim算法
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
int map[30][30];
int n;
int visit[30];//visit数组用来标记该点是否已经被选过,
void prim()
{
int dis[30],sum=0,min,i,j;//dis数组用来存放第i个点到已选择点集合的最短距离
for(i=1;i<=n;i++)
dis[i]=INT_MAX;//初始化所以的点到被选中的点集合的最短距离为无穷大
dis[1]=0;visit[1]=1;//初始化第一个点,然后从第一个点逐渐找离所选集合点的最短距离
int now=1;
for(j=1;j<=n;j++)
{
for(i=1;i<=n;i++)
{
if(!visit[i]&&dis[i]>map[now][i])//如果新加入的点到i的距离小于前面选过的点的距离,就更新
dis[i]=map[now][i];
}
int min=INT_MAX;
for(i=1;i<=n;i++)
if(!visit[i]&&dis[i]<min)//找到所选的点的集合离哪个未选的点距离最近,就把那个点加入该集合
min=dis[now=i];
visit[now]=1;//标记该点已访问过
}
for(i=1;i<=n;i++)
sum+=dis[i];
printf("%d\n",sum);
}
int main()
{
int i,j,k;
char x;
int p,q,z,y,ans,sum;
while(scanf("%d",&n),n!=0)
{
memset(visit,0,sizeof(visit));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
map[i][j]=INT_MAX;
for(i=1;i<n;i++)
{
getchar();
scanf("%c",&x);
p=x-'A'+1;
scanf("%d",&y);
while(y--)
{
getchar();
scanf("%c",&x);
q=x-'A'+1;
scanf("%d",&z);
map[q][p]=map[p][q]=z;
}
}
prim();
}
return 0;
}
本文深入探讨了最小生成树的概念,并通过Kruskal和Prim算法进行了实战演练。作者分享了对算法的理解,强调了算法背后的逻辑与应用价值。学习过程包括并查集的使用技巧,以及如何通过题目的数量来深化对知识点的理解。通过实践,作者不仅掌握了算法的实现,还学会了如何多角度思考和总结。文章以实际代码为例,详细展示了算法的实现过程。
337

被折叠的 条评论
为什么被折叠?



