There are two algorithms for finding the minimum spanning tree of undirected networks: Prim and Kruskal, both of which are common methods for generating the minimum spanning tree.
First, Prim algorithm:
Suppose G=(V,E) is a net graph, where V is the set of vertices and E is the set of edges. Starting from a vertex u1, the edge (u1, v) with the minimum weight associated with it is selected, and its vertex v is added to the vertex of the spanning tree
In collection U. U is used to store the vertices in the minimum spanning tree of G, and T is used to store the edges in the minimum spanning tree of G.
Let the initial value of set u be U={u1} (assuming the minimum spanning tree is constructed from vertex u1), and the initial value of set T be T = {}.
After each step, select a vertex u (U belongs to U) from u, and another vertex v belongs to the edge of V-U, select the edge (u,v) with the minimum weight, add the vertex v to the set u, and add the edge (u,v) to the set T. This is repeated until U=V, when the minimum spanning tree is constructed, the set t contains all the edges of the minimum spanning tree.
> > #include<iostream> > > #include<cstring> > > #include<algorithm> using namespace std; const int N=501,INF=0X3f3f3f3f; int n,m,g[N][N],dis[N]; bool st[N]; void prim(){ > > memset(dis,0x3f,sizeof(dis)); > > int res=0; > > for(int i=0;i<n;i++){ > > int t=-1; > > for(int j=1;j<=n;j++){ > > if(!st[j]&&(t==-1||dis[t]>dis[j])) > > t=j; > > } > > if(i&&dis[t]==INF){ > > cout<<"impossible"<<endl; > > return ; > > } > > if(i)res+=dis[t]; > > for(int j=1;j<=n;j++) > > dis[j]=min(dis[j],g[t][j]); > > st[t]=true; > > } > > cout<<res<<endl; } int main(void){ > > cin>>n>>m; > > memset(g,0x3f,sizeof(g)); > > for(int i=0,a,b,c;i<m;i++){ > > cin>>a>>b>>c; > > g[a][b]=g[b][a]=min(g[a][b],c); > > } > > prim(); return 0; }
Then we will talk about Kruskal: first, construct a subgraph with only n vertices and empty edge set, and regard each vertex in the subgraph as the root node of each tree, then, from the edge set E of the network Select an edge with the least weight. If two vertices of the edge belong to different trees, add them to the subgraph, that is, synthesize two trees into one tree. Otherwise, if two vertices of the edge have fallen on the same tree, it is not advisable. Instead, take the edge with the least weight and try again. And so on until there is only one tree in the forest, that is, the subgraph contains n-1 edges.
#include <stdio.h> #include <stdlib.h> #define Max 50 typedef struct road *Road; typedef struct road { int a , b; int w; }road; typedef struct graph *Graph; typedef struct graph { int e , n; Road data; }graph; Graph initGraph(int m , int n) { Graph g = (Graph)malloc(sizeof(graph)); g->n = m; g->e = n; g->data = (Road)malloc(sizeof(road) * (g->e)); return g; } void create(Graph g) { int i; for(i = 1 ; i <= g->e ; i++) { int x , y, w; scanf("%d %d %d",&x,&y,&w); if(x < y) { g->data[i].a = x; g->data[i].b = y; } else { g->data[i].a = y; g->data[i].b = x; } g->data[i].w = w; } } int getRoot(int v[], int x) { while(v[x] != x) { x = v[x]; } return x; } void sort(Road data, int n) { int i , j; for(i = 1 ; i <= n-1 ; i++) { for(j = 1 ; j <= n-i ; j++) { if(data[j].w > data[j+1].w) { road t = data[j]; data[j] = data[j+1]; data[j+1] = t; } } } } int Kruskal(Graph g) { int sum = 0; //Union checking set int v[Max]; int i; //init for(i = 1 ; i <= g->n ; i++) { v[i] = i; } sort(g->data , g->e); //main for(i = 1 ; i <= g->e ; i++) { int a , b; a = getRoot(v,g->data[i].a); b = getRoot(v,g->data[i].b); if(a != b) { v[a] = b; sum += g->data[i].w; } } return sum; } int main() { int m , n , id = 1; while(scanf("%d %d",&m,&n) != EOF) { int r , i; Graph g = initGraph(m,n); create(g); r = Kruskal(g); printf("Case %d:%d\n",id++,r); free(g); } return 0; }