本题链接:点击打开链接
本题大意:
有n个村庄m条路,输入每条路连接的村庄标号及权值,然后给出起点和终点,求其最小生成树的权值,若不能生成一棵树,则输出-1。
解题思路:
使用的是Prime算法,用所给的道路连接的村庄号作为下标,道路长度作为权值构建一个图,由所给起点开始依次查找距当前起点权值最小的点将其连上,更新未连点到所连图的权值,再次查找。具体请参见代码:
#include<stdio.h>
#include<string.h>
#define INF 0xffffff
int map[210][210];
int mark[220],lowcost[220];
int main()
{
int n,m,x,y,cost,s,e,vir;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
map[i][j]=INF;//将图初始化为无穷大
for(int k=0;k<m;k++)
{
scanf("%d%d%d",&x,&y,&cost);
if(map[x][y]>cost)//将每条路对应的编号及长度存到图中
map[x][y]=map[y][x]=cost;//由于来与往路的长度是相等的
}
scanf("%d%d",&s,&e);
memset(mark,0,sizeof(mark));//初始化标记数组
for(int i=0;i<n;i++)
{
lowcost[i]=map[s][i];//loecost数组中现在存放的是以s为起点到其余点的权值
}
lowcost[s]=0;
mark[s]=1;//将起始点权值变为0,并标记起始点
for(int k=1;k<n;k++)//有n个点,故需查找n-1次
{
int min=INF;
for(int i=0;i<n;i++)//每次均遍历所有点
{
if(!mark[i]&&lowcost[i]<min)//查找到距起始点权值最小的点
{
min=lowcost[i];
vir=i;//取出其坐标作为新的起点
}
}
if(min==INF)
break;
mark[vir]=1;//将查找到的点标记
// lowcost[vir]=0;
for(int j=0;j<n;j++)//更新各点的权值
// if(!mark[j]&&map[vir][j]<lowcost[j])
// {
// lowcost[j]=map[vir][j];
// mark[j]=vir;
// }
if(!mark[j]&&lowcost[j]>lowcost[vir]+map[vir][j])
lowcost[j]=lowcost[vir]+map[vir][j];
}
if(lowcost[e]==INF)
printf("-1\n");
else
printf("%d\n",lowcost[e]);
}
return 0;
}