题目描述
根据输入创建无向网。分别用Prim算法和Kruskal算法构建最小生成树。(假设:输入数据的最小生成树唯一。)
输入
顶点数n
n个顶点
边数m
m条边信息,格式为:顶点1顶点2权值
Prim算法的起点v
输出
输出最小生成树的权值之和
对两种算法,按树的生长顺序,输出边信息(Kruskal中边顶点按数组序号升序输出)
样例输入
6
v1 v2 v3 v4 v5 v6
10
v1 v2 6
v1 v3 1
v1 v4 5
v2 v3 5
v2 v5 3
v3 v4 5
v3 v5 6
v3 v6 4
v4 v6 2
v5 v6 6
v1
样例输出
15
prim:
v1 v3 1
v3 v6 4
v6 v4 2
v3 v2 5
v2 v5 3
kruskal:
v1 v3 1
v4 v6 2
v2 v5 3
v3 v6 4
v2 v3 5
代码
#include "bits/stdc++.h"
using namespace std;
typedef pair<int,int> PII;
const int maxn=1010,INF=0x3f3f3f3f;
int n,m,node[maxn][maxn],dis[maxn],vis[maxn],sum;
map<string,int> mp;
map<int,string> ins;
struct NODE{
int val,a,b;
bool operator<(const NODE &rp) const{
if(val==rp.val) {
return a<rp.a;
}
return val>rp.val;
}
};
priority_queue<NODE> q;
vector<NODE> ans;
void init(){
sum=0;
memset(dis,0x3f,sizeof dis);
memset(vis,0,sizeof vis);
}
void prim(int st){
q.push({0,0,st});
dis[st]=0;
while (!q.empty()){
auto it=q.top();
q.pop();
int v=it.val,a=it.a,b=it.b;
if(vis[b]) continue;
sum+=v;
vis[b]=1;
if(a) ans.push_back({a,b,v});
for(int i=1;i<=n;i++){
if(!vis[i] && dis[i]>node[b][i]){
dis[i]=node[b][i];
q.push({dis[i],b,i});
}
}
}
cout<<sum<<endl;
}
priority_queue<NODE> kq;
int f[maxn];
void kinit(){
sum=0;
for(int i=1;i<=n;i++){
f[i]=i;
}
memset(vis,0,sizeof vis);
}
int getfa(int x){
if(f[x]==x) return x;
return f[x]= getfa(f[x]);
}
void kruskal(){
int qwe=1;
while(qwe<n){
auto it=kq.top();
kq.pop();
int v=it.val,a=it.a,b=it.b;
int fa= getfa(a),fb= getfa(b);
if(fa==fb) continue;
qwe++;
cout<<ins[a]<<" "<<ins[b]<<" "<<v<<endl;
f[fa]=fb;
sum+=v;
}
// cout<<sum<<endl;
}
int main(){
// freopen("123.in","r",stdin);
cin>>n;
for(int i=1;i<=n;i++){
string s;
cin>>s;
mp[s]=i;
ins[i]=s;
}
cin>>m;
memset(node,0x3f,sizeof node);
for(int i=1;i<=m;i++){
string a,b;
int x,y,c;
cin>>a>>b>>c;
x=mp[a],y=mp[b];
node[x][y]=node[y][x]=c;
if(x<y) kq.push({c,x,y});
else kq.push({c,y,x});
}
string start;
cin>>start;
int st=mp[start];
init();
prim(st);
cout<<"prim:"<<endl;
for(auto it:ans){
cout<<ins[it.val]<<" "<<ins[it.a]<<" "<<it.b<<endl;
}
kinit();
cout<<"kruskal:"<<endl;
kruskal();
return 0;
}