def:对于一个边上具有权值的图,权值和最小的生成树
example:修建连接几个城市之间的公路,求最小花费
code:
map[][]:邻接矩阵存储图的信息
dis[i]:该数组之和为最小生成树的权值
其中对于集合A中表示最小生成树中包含i的边的的权值
example:修建连接几个城市之间的公路,求最小花费
code:
map[][]:邻接矩阵存储图的信息
dis[i]:该数组之和为最小生成树的权值
其中对于集合A中表示最小生成树中包含i的边的的权值
对于集合B中表示集合A中点与i点相连的最短边长
#include
#include
#include
using namespace std;
#define maxV 100
int map[maxV][maxV];
int vis[maxV];
int dis[maxV];
#define max 999999
int prim(int s, int v)
{
int minweight = 0;
int i,j;
/**初始化**/
for(i = 1; i <= v; i++)
{
dis[i] = map[s][i];
//由于初始时A集合中没有点,所以此时初始化的为B集合中的点到s点的距离
}
memset(vis,0,sizeof(vis)); //初始时所有点的都在集合B中
vis[s] = 1;//把第一个点放到从集合B中删除,放到集合A中
dis[s] = 0;//map[s][s] = 0
/*****************初始化完成**************************/
/*****************生成最小生成树**************************/
for(i = 1; i <= v-1; i++)//循环n-1次,每次加入一个点
{
int min = max;
int k = 0;
for(j = 1; j <= v; j++)//在集合B中找dis最小的点标记为K,
{
if(!vis[j] && dis[j] < min)
{
min = dis[j];
k = j;
}
}
if(k == 0)
return 0;//从s出发,没有可到达的点,说明此图不连通
vis[k] = 1; //把该点加入到集合A中
minweight += dis[k];
/*****更新边长*******/
for(j = 1; j <= v; j++)
{
//更新。对于每个与K相连的在B集合中未被取出的点,更新其到K的距离
if(!vis[j] && map[k][j] < dis[j])
{
dis[j] = map[k][j];
}
}
//进行下一次循环,此时集合A中所有点到B中点的距离的最短边长为map[k][j],
//j的父节点为K
}
return minweight;
}
int main()
{
int v,e;//点的个数、边的条数
int a,b,c;
int i;
while(~scanf("%d%d",&v,&e))
{
memset(map,max,sizeof(map));
memset(dis,-1,sizeof(vis));
for(i = 0; i < e; i++)//输入边
{
cin>>a>>b>>c;
if(map[a][b] > c)
{
map[a][b] = c;
map[b][a] = c;
}
else
{
map[a][b] = c;
map[b][a] = c;
}
}
cout<
<