prim(最小生成树模板)
程序员文章站
2022-06-16 08:58:18
...
描述
使用prim算法求某图的最小生成树的边的权值输出的序列。例如下图的最小生成树的权值输出序列为1 4 2 5 3,要求从V1顶点开始生成最小生成树。
输入
若干行整数
第一行为两个整数,分别为图的顶点数和边数
第二行开始是该图的邻接矩阵,主对角线统一用0表示,无直接路径的两点用100来表示(保证各边权值小于100)
输出
若干用空格隔开的整数
样例输入
6 10
0 6 1 5 100 100
6 0 5 100 3 100
1 5 0 5 6 4
5 100 5 0 100 2
100 3 6 100 0 6
100 100 4 2 6 0
样例输出
1 4 2 5 3
#include<iostream>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
const int N=100000+100;
const int M=3e6+1005;
int w[2000][2000];//储存边
int dist[2000];//保存到已选集合的最小权值
bool vis[2000];//标记是否已经被选
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
{
cin>>w[i][j];
if(w[i][j]==100)
w[i][j]=INF;
}
}
for(int i=2;i<=n;++i)//初始化
{
dist[i]=w[1][i];
}
int x=1;
vis[x]=1;
for(int i=1;i<n;++i) //n - 1次遍历
{
int minn=INF,k=x;
for(int j=1;j<=n;++j)
{//找到离已选集合最近的点
if(!vis[j]&&minn>=dist[j])
{
minn=dist[j];
k=j;
}
}
cout<<minn<<' ';//输出权值
x=k;
vis[x]=1;//标记已选
//cout<<x<<" ";
for(int j=1;j<=n;++j)
{//更新到已选集合的权值
if(!vis[j]&&dist[j]>=w[x][j])
{
dist[j]=w[x][j];
}
}
}
return 0;
}