您的位置:首页 > 其它

图论——最小生成树Prim算法模板

2018-03-30 19:35 387 查看
1Prim算法基本思想:以顶点为主导地位,从起始顶点出发,通过选择当前可用的最小权值边依次把其他顶点加入到生成树当中来。
2  Prim 算法模板,prim算法适合稠密图,时间复杂度与边的数目无关,与顶点个数有关。
//不用输出最小生成树的选择边
//算法书中的模板,具体的题目,可以适当改变其中的代码;//QS通信,每条边的权值需要每个QS的适配器价格,和两个QS之间网线的价格
//只需要计算追销生成树的权值

#include<stdio.h>
#include<string.h>
#define N 1010
#define MAX 1000000
int edge

;
int adapter
;//每个QS喜欢的适配器的价格
int lowcost
;//充当prim算法中两个数组(lowcost数组和vis数组)的作用
int t;//测试数据的组数
int n; //每个测试数据中QS的个数
void init()
{
int i,j; //循环变量
scanf("%d",&n); //QS的个数
for(i=0;i<n;i++)
scanf("%d",&adapter[i]);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&edge[i][j]);
if(i==j) edge[i][j]=MAX;
else edge[i][j]+=adapter[i]+adapter[j];
}
}
memset(lowcost,0,sizeof(lowcost));
}
void prim()
{
int i,j;//循环变量
int sum=0; //最小生成树权值
lowcost[0]=-1 ;// 从顶点0开始构造最小生成树
for(i=1;i<n;i++)
lowcost[i]=edge[0][i];
for(i=1;i<n;i++)
{
int min=MAX,k;
for(j=0;j<n;j++)
{
if(lowcost[j]!=-1&&lowcost[j]<min)
{
k=j;
min=lowcost[j];
}
}
sum+=min;
lowcost[k]=-1;
for(j=0;j<n;j++)
{
if(edge[k][j]<lowcost[j])
lowcost[j]=edge[k][j];
}
}//end for
printf("%d\n",sum);
}
int main()
{
freopen("input.txt","r",stdin);
scanf("%d",&t);
while(t--)
{
init();
prim();
}
return 0;
}//输出最小生成树的选择边#include<stdio.h>
#include<string.h>
//prim 模板 记录了最小生成树选择的边
#define N 505
#define INF 1000000
int vis
;//标记前驱
int edge

;//邻接矩阵
int lowcost
;
int n;//顶点
int m;//边数
void prim(int u0)
{
int i,j;
int sumweight=0;//生成树权值
for(i=1;i<=n;i++) //初始化lowcost数组和vis数组
{
lowcost[i]=edge[u0][i];
vis[i]=u0;
}
vis[u0]=-1;
for(i=1;i<n;i++)//找除去原点u0外,其他顶点
{
int min=INF;
int pot=-1;
for(j=1;j<=n;j++)
{
if(vis[j]!=-1&&lowcost[j]<min)
{
pot=j;
min=lowcost[j];
}
}
if(pot!=-1)//表示没有找到权值最小的边
{
printf("%d %d %d\n",vis[pot],pot,lowcost[pot]);//输出前驱,
vis[pot]=-1;
sumweight+=lowcost[pot];
for(j=1;j<=n;j++)
{
if(vis[j]!=-1&&edge[pot][j]<lowcost[j])
{
lowcost[j]=edge[pot][j];
vis[j]=pot;
}
}//更新 lowcost数组 和 vis数组
} //end if
} //外层for
printf("%d\n",sumweight);//最小生成树权值
}
int main()
{
freopen("input.txt","r",stdin);
int i,j; //循环变量
int u,v,w;//起点,终点,权值
scanf("%d%d",&n,&m);
memset(edge,0,sizeof(edge));
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
edge[u][v]=edge[v][u]=w; //构造邻接矩阵
}
for(i=1;i<=n;i++) //对邻接矩阵赋初值
{
for(j=1;j<=n;j++)
{
if(i==j) edge[i][j]=0;
else if(edge[i][j]==0)
edge[i][j]=INF;
}
}
prim(1);
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: