#最小生成树---克鲁斯卡尔算法
#include <iostream>
#include<bits/stdc++.h>
#include <queue>
using namespace std;
struct Edge
{
int x, y;
int weight;
bool operator<(const Edge &e) const
{
return weight > e.weight;
}
Edge(){};
Edge(int a, int b, int c)
{
x = a;
y = b;
weight = c;
}
}edge[1000];
int uf[1000];
int sum=0;
int uf_find(int x)
{
if(uf[x]<0)
return x;
else
return uf_find(uf[x]);
}
bool uf_union(int x, int y)
{
int xroot = uf_find(x);
int yroot = uf_find(y);
if(xroot == yroot)
return false;
uf[yroot] = xroot;
return true;
}
void kruskal(int v,int e)
{
int n = 1;
priority_queue<Edge> Q;
for(int i=1;i<=e;i++)
Q.push(Edge(edge[i].x,edge[i].y,edge[i].weight));
while(!Q.empty() && n < v)
{
Edge e = Q.top();
Q.pop();
if(uf_union(e.x, e.y))
{
sum=sum+e.weight;
cout << e.x << " " << e.y << " " << e.weight << endl;
n++;
}
}
}
int main()
{
memset(uf, -1, sizeof(uf));
int v, e;
cout<<"输入顶点和边的个数"<<endl;
cin >> v >> e;
cout<<"输入边的定点和权值"<<endl;
for(int i=1;i<=e; i++)
{
cin >> edge[i].x >> edge[i].y >> edge[i].weight;
}
cout<<endl;
cout<<"输出选中的边"<<endl;
kruskal(v,e);
cout<<"权值"<<sum<<endl;
}
测试数据
7 12
1 2 2
1 4 1
1 3 4
2 5 10
2 4 3
5 4 7
5 7 6
7 4 4
7 6 1
6 4 8
6 3 5
3 4 2
最小生成树的权值和:16
改变并查集之后
#include<iostream>
#include<queue>
#include<bits/stdc++.h>
using namespace std;
struct Edge
{
int x,y;
int w;
bool operator <(const Edge & e) const
{
return w>e.w;
}
Edge() {};
Edge(int a,int b,int c)
{
x=a;
y=b;
w=c;
}
} edge[1000];
int pre[1000];
int sum=0;
int findd(int x)
{
int r=x;
while(r!=pre[r])
r=pre[r];
int i=x;
int j;
while(i!=r)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
bool unionn(int x,int y)
{
if(findd(x)==findd(y))
return false;
pre[findd(x)]=findd(y);
return true;
}
void kruskal(int e,int v)
{
int n=1;
priority_queue<Edge> Q;
for(int i=1; i<=e; i++)
Q.push(Edge(edge[i].x,edge[i].y,edge[i].w));
while(n<v&&!Q.empty())
{
Edge h=Q.top();
Q.pop();
if(unionn(h.x,h.y))
{
sum=sum+h.w;
cout<<h.x<<" "<<h.y<<" "<<h.w<<endl;
n++;
}
}
}
int main()
{
int v,e;
cout<<"输入顶点数和边数"<<endl;
cin>>v>>e;
for(int i=1; i<=e; i++)
pre[i]=i;
cout<<"输入各条边的顶点和权重"<<endl;
for(int i=1; i<=e; i++)
{
cin>>edge[i].x>>edge[i].y>>edge[i].w;
}
cout<<endl;
cout<<"输出选择的边"<<endl;
kruskal(e,v);
cout<<"输出总权重"<<sum<<endl;
return 0;
}