编写一个程序,计算给定加权图G=(V,E)的最小生成树的各边权值之和。
输入:
第一行输入G的定点数n。接下来n行输入表示G的n*n的邻接矩阵A。A的元素aij代表顶点i到顶点j的边的权值。
另外,便不存在时记为-1.
输出:
输出G的最小生成树的各边权值总和,占1行。
限制:
1<=n<=100 0<=aij<=200 (aij!=-1时) aij=aji G为连通图。
输入示例:
5
-1 2 3 1 -1
2 -1 -1 4 -1
3 -1 -1 1 1
1 4 1 -1 3
-1 -1 1 3 -1
输出示例:
5
代码:
#include<iostream>
using namespace std;
const int maxn=100;
const int INF=(1<<21);
int n,M[maxn][maxn];//邻接矩阵,记录u到v的边的权值
int prim()
{
int u,minv;
int d[maxn];//记录连接T内顶点与V-T内顶点的边中,权值最小的边的权值
int p[maxn];//记录最小生成树中顶点v的父节点
int color[maxn];//记录v的访问状态0 1 2
for(int i=0;i<n;i++)
{
d[i]=INF;
p[i]=-1;
color[i]=0;
}
d[0]=0;
while(1)
{
minv=INF;
u=-1;
for(int i=0;i<n;i++)
{
if(minv>d[i]&&color[i]!=2)
{
u=i;
minv=d[i];
}
}
if(u==-1)
break;
color[u]=2;
for(int v=0;v<n;v++)
{
if(color[v]!=2&&M[u][v]!=INF)//color[v]!=2,并且u v之间存在边
{
if(d[v]>M[u][v])
{
d[v]=M[u][v];
p[v]=u;
color[v]=1;
}
}
}
}
int sum=0;
for(int i=0;i<n;i++)
{
if(p[i]!=-1)
sum+=M[i][p[i]];
}
return sum;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
int e;
cin>>e;
M[i][j]=(e==-1)?INF:e;
}
}
cout<<prim()<<endl;
return 0;
}
今天也是元气满满的一天! good luck !