【问题描述】Prim算法解决的是带权重的无向图上连接所有顶点的耗费最小的生成树。Q使用最小堆数据结构。
【输入形式】在屏幕上输入顶点个数和连接顶点间的边的权矩阵。
【输出形式】顺序输出按照贪心选择得到的各顶点序号,及该顶点的前驱顶点序号,及路径长度。
【样例1输入】
8
0 15 7 0 0 0 0 10
15 0 0 0 0 0 0 0
7 0 0 9 12 5 0 0
0 0 9 0 0 0 0 0
0 0 12 0 0 6 0 0
0 0 5 0 6 0 14 8
0 0 0 0 0 14 0 3
10 0 0 0 0 8 3 0
【样例1输出】
3 1 7
6 3 5
5 6 6
8 6 8
7 8 3
4 3 9
2 1 15
【样例说明】
输入:顶点个数为8。连接顶点间边的权矩阵大小为8行8列,位置[i,j]上元素值表示第i个顶点到第j个顶点的距离,0表示两个顶点间没有边连接。
输出:顺序输出按照贪心选择得到的各顶点序号,及该顶点的前驱顶点序号,及路径长度。
【评分标准】根据输入得到准确的输出。
【代码实现】
#include <bits/stdc++.h>
using namespace std;
int inf=1000000;//无穷大
int n,g[200][200];
int dis[200],vis[200];
struct edge
{
int u,v,d;
bool operator < (const edge &x) const
{
return d>x.d;
}
};
void prime(int n)
{
priority_queue<edge> q;
int a=1,b=0;
for(int i=1;i<=n;i++)
{
if(i!=a)
{
dis[i]=g[a][i];
q.push({a,i,g[a][i]});
}
}
while(!q.empty())
{
edge t=q.top();
q.pop();
int u=t.u,v=t.v,d=t.d;
if(vis[v]!=0) continue;
vis[v]=1;
b++;
cout<<v<<" "<<u<<" "<<d<<endl;
if(b==n-1) break;
a=v;
for(int i=1;i<=n;i++)
{
if(!vis[i]&&g[a][i]<dis[i])
{
dis[i]=g[a][i];
q.push({a,i,g[a][i]});
}
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>g[i][j];
if(g[i][j]==0)
g[i][j]=inf;
}
}
prime (n);
return 0;
}