题目描述
根据输入创建无向网。分别用Prim算法和Kruskal算法构建最小生成树。(假设:输入数据的最小生成树唯一。)
输入
顶点数n
n个顶点
边数m
m条边信息,格式为:顶点1顶点2权值
Prim算法的起点v
输出
输出最小生成树的权值之和
对两种算法,按树的生长顺序,输出边信息(Kruskal中边顶点按数组序号升序输出)
输入样例1 | 输出样例1 |
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\n prim:\n v1 v3 1\n v3 v6 4\n v6 v4 2\n v3 v2 5\n v2 v5 3\n kruskal:\n v1 v3 1\n v4 v6 2\n v2 v5 3\n v3 v6 4\n v2 v3 5\n |
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
struct line_message{
int va,vb;
int weight;
};
class min_tree{
int t_v;
string *v;
int t_message;
line_message *l;
int **st;//邻接矩阵//其实没用到
int prim_root;
line_message *prim_tree,*kruskal_tree;
public:
min_tree(){}
min_tree(int t_v1,int t_m1,string *v1,line_message *l1,int root):t_v(t_v1),t_message(t_m1),prim_root(root){
v = new string [t_v1];
l = new line_message [t_m1];
st = new int *[t_v];
for(int i = 0 ; i < t_v ; i++ ){
v[i] = v1[i];
st[i] = new int [t_v];
for(int j = 0 ; j < t_v ; j++){
st[i][j] = 0;
}
}
for(int i = 0 ; i < t_message ; i++ ){
l[i].va = l1[i].va;l[i].vb = l1[i].vb;l[i].weight = l1[i].weight;
for(int j = 0 ; j < t_v ; j++ ){
for(int k = 0 ; k < t_v ; k++ ){
if(l[i].va == j&&l[i].vb == k){
st[j][k] = l[i].weight;
}
}
}
}
}
void prim();
void kruskal();
};
void min_tree::prim(){//prim2方法,非蛮力,所以会看着眼花
int *tree_v = new int [t_v];
for(int i = 0 ; i < t_v ; i++ ){
tree_v[i] = 0;
}
tree_v[prim_root] = 1;
prim_tree = new line_message[t_v-1];
line_message *test = new line_message[t_message];
for(int i = 0 ; i < t_message ; i++ ){
test[i].va = l[i].va;
test[i].vb = l[i].vb;
test[i].weight = 10001;
if(test[i].va==prim_root||test[i].vb==prim_root){
test[i].weight = l[i].weight;
}
}
int sum = 0;
for(int j = 0 ; j <t_v-1 ; j++){
int min = 999;int min_i =1000;
for(int i = 0 ; i < t_message ; i++ ){
if(test[i].weight!=0){
if(test[i].weight < min&&(tree_v[test[i].va]==0||tree_v[test[i].vb]==0)){
min = test[i].weight;min_i = i;
}
}
}
if(tree_v[test[min_i].va]==0){
swap(test[min_i].va,test[min_i].vb);
}
tree_v[test[min_i].va] =1;tree_v[test[min_i].vb] =1;
prim_tree[j].va = test[min_i].va;
prim_tree[j].vb = test[min_i].vb ;
prim_tree[j].weight = test[min_i].weight;
sum = sum + test[min_i].weight;
test[min_i].weight = 0;//标记
for(int i = 0 ; i < t_message ; i++ ){
if(test[i].weight==10001&&(test[i].va==test[min_i].va||test[i].vb==test[min_i].va
||test[i].va == test[min_i].vb||test[i].vb == test[min_i].vb)){
test[i].weight = l[i].weight;
}
}
}
cout<<sum<<endl<<"prim:"<<endl;
for(int i = 0 ;i < t_v-1 ; i++ ){
cout<<v[prim_tree[i].va]<<" "<<v[prim_tree[i].vb]<<" "<<prim_tree[i].weight<<endl;
}
// int *state = new int [t_v];
// for(int i = 0 ; i < t_v ; i++ ){
// state[i] = 1000;//初始化
// if(v[i] == prim_root){
// state[i] = 0;
// }
// }
}
void min_tree::kruskal(){
kruskal_tree = new line_message[t_v-1];
line_message *test = new line_message[t_message];
for(int i = 0 ; i < t_message ; i++ ){
test[i].va = l[i].va;
test[i].vb = l[i].vb;
test[i].weight = l[i].weight;
}
int *tree_v = new int [t_v-1];
for(int i = 0 ; i < t_v ; i++ ){
tree_v[i] = i;
}
for(int k = 0,i = 0 ; k < t_v-1 ; ){
// int min =999,i_min = 1000;
if(tree_v[test[i].va]!=tree_v[test[i].vb]){
kruskal_tree[k].va = test[i].va;
kruskal_tree[k].vb = test[i].vb;
kruskal_tree[k].weight = test[i].weight;
for(int j = 0 ; j < t_v ; j++ ){
if(j!=test[i].va&&tree_v[j]==tree_v[test[i].va])
tree_v[j]=tree_v[test[i].vb];
}
tree_v[test[i].va]=tree_v[test[i].vb];
k++;
}
i++;
}
cout<<"kruskal:"<<endl;
for(int i = 0 ; i < t_v-1 ; i++ ){
cout<<v[kruskal_tree[i].va]<<" "<<v[kruskal_tree[i].vb]<<" "<<kruskal_tree[i].weight<<endl;
}
}
bool cmp(line_message l1,line_message l2){
return l1.weight < l2.weight;
}
int main(){
int t;
cin>>t;
string *v = new string [t];
for(int i = 0 ; i < t ; i++ ){
cin>>v[i];
}
int t_message;
cin>>t_message;
line_message *l1 = new line_message [t_message];
string sa,sb;
for(int i = 0 ; i < t_message ; i++ ){
cin>>sa>>sb>>l1[i].weight;
for(int j = 0 ; j < t ; j++ ){
if(sa == v[j])
l1[i].va = j;
else if(sb == v[j])
l1[i].vb = j;
}
if(l1[i].va>l1[i].vb)
swap(l1[i].va,l1[i].vb);
}
sort(l1,l1+t_message,cmp);
string prim_root;
cin>>prim_root;
int i_root;
for(int i = 0 ; i < t ; i++ ){
if(prim_root==v[i])
i_root = i;
}
min_tree t1(t,t_message,v,l1,i_root);
t1.prim();
t1.kruskal();
return 0;
}