题目描述
题目出处:点这里
输入格式
输出格式
样例
输入
3
0 1 2
1 0 1
2 1 0
输出
2
提示
样例说明
分析与思路
这个题与我们在介绍Prim算法时所举出的例题的不同之处在于:例题所求的值是最小生成树,而本题所求的是最小生成树各边权之和所以相较于介绍Prim算法时列出的代码,在这个题目当中需要进行一些更改。
更改在哪里
让我们先回顾一下在介绍Prim算法时的代码
vector<Node> Prim(int sid){
vector<Node>result;
memset(flag,false,sizeof(flag));
pque.push(Node(-1,sid,0));
while(result.size()<n-1){
Node nd=pque.top();pque.pop();
if(flag[nd.id])continue;
flag[nd.id]=true;
// if(nd.from!=-1)result.push_back(nd);
if(nd.id!=sid)result.push_back(nd);
for(Node df:g){
if(!flag[df.id]&&df.from==nd.id){//判定时不再需要判断是否存在这条边
//需要判断这条边是否连接了该顶点和其他定点
pque.push(Node(nd.id,df.id,df.w));
}
}
}
return result;
}
在这段代码中,函数的返回值是一个记录了最小生成树的可变长数组,而我们要求的是最小生成树的边权值之和,所以我们应该在寻找最小生成树的时候来统计
,最后再让函数返回统计值做为答案
int Prim(int sid){
int result=0,sum=0;
//统计值 记录已经统计了多少条边
memset(flag,false,sizeof(flag));
pque.push(Node(-1,sid,0));
while(sum<n){//当统计的边的数量达到n-1(形成最小生成树)结束循环
Node nd=pque.top();pque.pop();
if(flag[nd.id])continue;
flag[nd.id]=true;
sum++;//每次统计边时需要同时增加
// if(nd.from!=-1)result.push_back(nd);
if(sum!=1)result+=nd.w;
//这里不再是记录树的边,而是记录树的边权总和
for(int i=1;i<=n;i++){
if(!flag[i]&&g[nd.id][i]<MXV){
pque.push(Node(nd.id,i,g[nd.id][i]));
}
}
}
return result;
}
那么按照这些思路,我们就可以轻松解出这道题了
代码实现
#include<bits/stdc++.h>
using namespace std;
const int MXV=0x3f3f3f3f;
const int MXN=300;
int n;
int a,b,len;
struct Node{
int from,id,w;
Node(){}
Node(int i,int d,int l){
from=i;id=d;w=l;
}
friend bool operator < (Node a,Node b){
return a.w>b.w;
}
};
bool flag[MXN+1];
priority_queue<Node>pque;
int g[MXN+1][MXN+1];
int Prim(int sid){
int result=0,sum=0;
//统计值 记录已经统计了多少条边
memset(flag,false,sizeof(flag));
pque.push(Node(-1,sid,0));
while(sum<n){//当统计的边的数量达到n-1(形成最小生成树)结束循环
Node nd=pque.top();pque.pop();
if(flag[nd.id])continue;
flag[nd.id]=true;
sum++;//每次统计边时需要同时增加
// if(nd.from!=-1)result.push_back(nd);
if(sum!=1)result+=nd.w;
//这里不再是记录树的边,而是记录树的边权总和
for(int i=1;i<=n;i++){
if(!flag[i]&&g[nd.id][i]<MXV){
pque.push(Node(nd.id,i,g[nd.id][i]));
}
}
}
return result;
}
int main(){
memset(g,0x3f,sizeof(g));
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>len;
g[i][j]=g[j][i]=len;
}
}
cout<<Prim(1);
return 0;
}