//最小生成树
/*
算法思想:
尽量使用短边
Kruskal算法 贪心算法
切分定理 :
图中的顶点分为两部分
就称为一个切分
如果一个边的两个端点,属于切分不同的两边,这个边
称为横切边
二分图:找到一组切分,使得所有的边都是横切边
切分定理:
横切边中的最短边,属于最小生成树
Kruskal算法每次选择一个最短边,如果这个边没有形成环
*/
/*
首先是确定这个图是联通的
*/
#include<fstream>
#include<iostream>
#include<map>
#include<set>
#include<algorithm>
#define max 10
using namespace std;
typedef struct WeightedEdge{
int v, d, w;
bool operator < (const WeightedEdge &e)const{
return w < e.w;
}
}E;
typedef struct Graph{
int v,e;
multiset<E> edge;
}G;
class Union{
public:
int parent[max];
int rank[max];//rank[i]表示 i节点的根节点的层数
Union(int v){//v为并查集大小
for(int i = 0; i < v; i++){
parent[i] = i;
rank[i] = 1;
}
}
int find(int p){
if(p >= max || p < 0) return -1;
while(p != parent[p]){//说明已经找到根节点了
parent[p] = parent[parent[p]];
p = parent[p];
}
return p;
}
bool isConnected(int p, int q){
return find(p) == find(q);
}
void unionele(int p, int q){
int p_root = find(p);
int q_root = find(q);
if(p_root == q_root) return;
if(rank[p_root] > rank[q_root]){
parent[q_root] = p_root;
}
else if(rank[p_root] < rank[q_root]){
parent[p_root] = q_root;
}
else{
parent[q_root] = p_root;
rank[p_root]++;
}
}
};
void initG(G* g);
int Kruskal(G* g);
int mst[max];
int main(){
G* g = new G;
initG(g);
int sum = Kruskal(g);
cout <<"sum: "<< sum << endl;
for(int i = 0; i < g->v; i++){
cout<< i << mst[i]<<endl;
}
return 0;
}
void initG(G* g){
ifstream infile;//输入流
infile.open("Kruskal.txt",ios::in);
if(!infile.is_open()){
cout << "Flie open failure" <<endl;
return;
}
infile >> g->v >> g->e ;
//Input the edge and weight
E e1;
for(int i = 0; i < g->e; i++){
int node1,node2,weight;
infile >> node1 >> node2 >> weight;
e1.v = node1;
e1.d = node2;
e1.w = weight;
g->edge.insert(e1);
}
infile.close();
fill(mst,mst+10,-1);
}
int Kruskal(G* g){
//当时存储边的时候使用的multiset
//边已经按从小到大排列好了
Union u(g->v);
E e;
int sum = 0;
//所以这里只需要遍历每一条边就行了
for(multiset<E>::iterator it = g->edge.begin(); it != g->edge.end(); it++){
e = *it;
if(!u.isConnected(e.v,e.d)){//如果这两个点不相连 ,如果相连就直接跳过
u.unionele(e.v, e.d);//将这两个点合并
sum += e.w;
if(mst[e.v] == -1){
mst[e.v] = e.d; //存储在最小树中
}
else
mst[e.d] = e.v;
}
}
return sum;
}
Kruskal
最新推荐文章于 2024-01-03 19:43:41 发布