问题:
1.1在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集(即)且为无循环图,使得到的 w(T) 最小,则此 T 为 G 的最小生成树。
1.2在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集(即)且为无循环图,使得到的 w(T) 最小,则此 T 为 G 的最小生成树。
解析:
2.1输入:一个加权连通图,其中顶点集合为V,边集合为E,初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;重复下列a,b操作,直到Vnew = V:
a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合Vnew中,将<u, v>边加入集合Enew中,最终得到最小生成树
2.2先构造一个只含 n 个顶点、而边集为空的子图,把子图中各个顶点看成各棵树上的根结点,之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,即把两棵树合成一棵树,反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直到森林中只有一棵树,也即子图中含有 n-1 条边为止。
设计:
//Prim
#include<stdio.h>
#define ed 1000
int main()
{
int dianshu,bianshu,i,j,k,min,a,b,c,count=0,sum=0;
int er[10][10],dis[10],book[10]={0};
scanf("%d%d",&dianshu,&bianshu);
for(i=1;i<=dianshu;i++)
for(j=1;j<=dianshu;j++)
{
if(i==j)
er[i][j]=0;
else
er[i][j]=ed;
}
for(i=1;i<=bianshu;i++)
{
scanf("%d%d%d",&a,&b,&c);
er[a][b]=c;
er[b][a]=c;
}
//Kruskal
#include<stdio.h>
struct edge
{
int u;
int v;
int w;
};
struct edge e[1000];
int n,m;
int f[1000]={0},sum=0,count=0;
void quicksort(int l,int r)
{
int i,j;
struct edge t;
if(l>r)
return;
i=l;
j=r;
while(i!=j)
{
while(e[j].w>=e[l].w&&i<j)
j¨C;
while(e[i].w<=e[l].w&&i<j)
i++;
if(i<j)
{
t=e[i];
e[i]=e[j];
e[j]=t;
}
}
t=e[l];
e[l]=e[i];
e[i]=t;
quicksort(l,i-1);
quicksort(i+1,r);
return;
}
int getf(int v)
{
if(f[v]v)
return v;
else
{
f[v]=getf(f[v]);
return f[v];
}
}
int blending(int v,int u)
{
int t,p;
t=getf(v);
p=getf(u);
if(t!=p)
{
f[p]=t;
return 1;
}
return 0;
}
int main()
{
int i;
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(blending(e[i].u,e[i].v))
{
count++;
sum+=e[i].w;
}
if(countn-1)
break;
}
printf("%d\n",sum);
return 0;
}
分析:
Prim复杂度为O(n^2)
Kruskal复杂度为O(nlogn)
本文介绍了两种求解加权连通图最小生成树的方法——Prim和Kruskal算法。Prim算法从一个顶点开始,逐步添加权值最小的边,直至构建完整个无环树。Kruskal算法则通过快速排序选取权值最小的边,避免形成环路,直至连接所有顶点。两种算法的时间复杂度分别为O(n^2)和O(nlogn)。
1605

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



