prim算法(矩阵形式):
#define inf 0x3f3f3f3f
int prim(int n,int sta)//n表示有n个顶点,sta表从sta这个顶点出发生成最小生成树
{
int mark[M],dis[M];
int i,sum = 0;
//sum是总的最小生成树边权值
for (i = 0;i < n;i ++) //初始化dis[i] 表从顶点sta到点i的权值
{
dis[i] = mat[sta][i];
mark[i] = 0;
}
mark[sta] = 1;
//sta 这个顶点加入最小生成树中
for (i = 1;i < n;i ++)
//循环n-1次,每次找出一条最小权值的边 n个点的图
{
//只有n-1条边
int min = inf;
//inf 表无穷大
for (j = 0;j < n;j ++)//找出当前未在最小生成树中边权最小的顶点
if (!mark[j] && dis[j] < min)
min = dis[j],flag = j;
mark[flag] = 1;
//把该顶点加入最小生成树中
sum += dis[flag];
//sum加上其边权值
for (j = 0;j < n;j ++)
//以falg为起点更新到各点是最小权值
if (dis[j] > mat[flag][j])
dis[j] = mat[flag][j];
}
return sum;
//返回边权总和
}
prim算法(边表形式):
struct Edge//frm为起点,to为终点,w为边权,nxt指向下一个顶点
{
// int frm;
int to,w,nxt;
}edge[M];
int vis[M],head[M],dis[M];
void addedge (int cu,int cv,int cw)//生成边的函数
{
//edge[e].frm = cu;
edge[e].to = cv;
edge[e].w = cw;
edge[e].nxt = head[cu];
head[cu] = e ++;
//edge[e].frm = cv;
edge[e].to = cu;
edge[e].w = cw;
edge[e].nxt = head[cv];
head[cv] = e ++;
}
int prim(int n,int sta) //n为顶点数量,sta为起点
{
int sum = 0;
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
for (i = head[sta];i != -1;i = edge[i].nxt)//遍历与sta点相连的所有顶点
{
int v = edge[i].to;
dis[v] = edge[i].w;
}
vis[sta] = 1; //加入到最小生成树中
int m = n - 1;
//只生成n-1条边,所以循环n-1次
while (m --)
{
int min = inf;
for (i = 0;i < n;i ++)//找出当前边权最小的边
if (!vis[i]&&dis[i] < min)
flag = i,min = dis[i];
sum += dis[flag];
vis[flag] = 1;//加入到最小生成树中
for (i = head[flag];i != -1;i = edge[i].nxt)//更新与flag顶点相连的点的dis
{
//
int v = edge[i].to;
if (edge[i].w < dis[v])
dis[v] = edge[i].w;
}
}
return sum; //返回边权总和
}
int main ()
{
e = 0;
//记得初始化
memset (head,-1,sizeof(head));
scanf ("%d %d %d",&a,&b,&w);
addedge(a,b,w);
.....
.....
prim(n,sta);
return 0;
}
Kruskal算法:
struct Edge
{
int v1,v2,w;
}edge[M],tree[M];
//w为v1顶点到v2顶点的边权
/ *
int Find (int parent[],int u)//第1种写法
{
int tmp = u;
while (paren[tmp] != -1)
tmp = parent[tmp];
return tmp;
}
*/
int Find (int u) //第2种写法
{
if (u != parent[u])
parent[u] = Find(paren[u]);
return parent[u];
}
bool cmp (Edge a,Edge b)
{
return a.w < b.w;
}
int Kruskal()//parent[]表示集合
{
int parent[M];
int i,j,sum,vf1,vf2;
sort(edge,edge+E,cmp);
//
memset (parent,-1,sizeof(parent));//对应第1种并查集的初始化
for (i = 0;i < n;i ++)
//对应第2种并查集的安始化
parent[i] = i;
sum = i = j = 0;
while (i < E && j < N - 1)//生成的边数为N-1
{
vf1 = Find(parent,edge[i].v1);
//找这两个点的祖先
vf2 = Find(parent,edge[i].v2);
if (vf1 != vf2)
//若两个点的祖先不同,说明不在同一集合
{
parent[vf2] = vf1;
//把vf2点加到vf1点的集合中
tree[j++] = edge[i]; //把边加到tree[]数组中,这句题目没要求可忽略之
sum += edge[i].w;
//sum 加上其边权
}
i ++;
}
return sum;
}
#define inf 0x3f3f3f3f
int prim(int n,int sta)//n表示有n个顶点,sta表从sta这个顶点出发生成最小生成树
{
}
prim算法(边表形式):
struct Edge//frm为起点,to为终点,w为边权,nxt指向下一个顶点
{
}edge[M];
int vis[M],head[M],dis[M];
void addedge (int cu,int cv,int cw)//生成边的函数
{
}
int prim(int n,int sta) //n为顶点数量,sta为起点
{
}
int main ()
{
}
Kruskal算法:
struct Edge
{
}edge[M],tree[M];
/ *
int Find (int parent[],int u)//第1种写法
{
}
*/
int Find (int u)
{
}
bool cmp (Edge a,Edge b)
{
}
int Kruskal()//parent[]表示集合
{
}