POJ2485 greedy algorithm for minimum spanning tree prim algorithm and kruskal algorithm
Title Analysis
http://poj.org/problem?id=2485
The input of this problem is adjacency matrix, any two points are directly connected, which is a typical problem of finding the minimum spanning tree.
prim algorithm
Starting from the source point, the minimum weight is selected from all optional edges (the starting point is in the current spanning tree but the ending point is not) and added to the current spanning tree until the number of edges is n-1. If the number of edges is less than n-1, but the minimum weight edge cannot be selected, then there is no minimum spanning tree. (perform n-1 selection operations, if you can't select halfway, there is no minimum spanning tree.)
An array is used to record whether each point is in the current minimum spanning tree, and an array is used to record the shortest edge length of the current minimum spanning tree from all points (initialized as the shortest edge length of the root distance from all other points, and updated with the shortest edge length of each newly added point distance from all points). The adjacency table or adjacency matrix can be used to store the graph Adjacency matrix.
#include<stdio.h> #include<string.h> using namespace std; const int INF=0x3f3f3f; const int MAXN=505; bool vis[MAXN]; int lowc[MAXN]; int prim(int mat[][MAXN],int n){ int max = 0; memset(vis,false,sizeof(vis)); memset(lowc,INF,sizeof(lowc)); //initialize vis[0] = true; for(int i = 0;i < n;i++){ lowc[i] = mat[0][i]; } //n-1 loops for(int i = 1;i < n;i++){ int p = -1;//added dot int min = INF; for(int j = 0;j < n;j++){ if(!vis[j]&&min>lowc[j]){ min = lowc[j]; p = j; } } if(p == -1) return -1; if(min > max) max = min; vis[p] = true; //update lowc[] for(int j = 0;j < n;j++){ if(lowc[j]>mat[p][j]) lowc[j] = mat[p][j]; } } return max; } int main(){ int T; scanf("%d",&T); while(--T!=-1){ int N; scanf("%d",&N); int mat[MAXN][MAXN]; for(int i = 0;i < N;i++){ for(int j = 0; j < N;j++){ scanf("%d",&mat[i][j]); } } printf("%d\n",prim(mat,N)); } return 0; }
1304K 172MS
kruskal Algorithm
All the edges are sorted according to the weight, and each edge is traversed from small to large. If the two points connected by the edge are not in the same connected component, the edge is added to the minimum spanning tree. If all points are not in the same connected component, then there is no minimum spanning tree; if all points are in a connected component, then the minimum spanning tree is found.
kruskal algorithm uses a parallel search set. Thought: https://blog.csdn.net/qq_41754350/article/details/81271567, https://blog.csdn.net/zjy_code/article/details/80634149
#include<stdio.h> #include<string.h> #include<vector> #include<algorithm> using namespace std; const int INF=0x3f3f3f; const int MAXN=505; int f[MAXN];//Union checking set int fcnt = 0;//Number of different connected components void UFinit(int n){//Initialize and check n unrelated elements in the set for(int i = 0;i < n;i++){ f[i] = i; } fcnt = n; } int find(int a){//Find the representative elements of the set a is in return a==f[a]?f[a]:find(f[a]); } bool Union(int a,int b){//Merge the set of a and b if(find(a)!=find(b)){ f[find(a)] = find(b); fcnt--; return true; } else return false; } struct Edge{ int cost,u,v; Edge(int cost_,int u_,int v_){ cost = cost_; u = u_; v = v_; } }; vector<Edge> e; bool cmp(Edge x,Edge y){ return x.cost < y.cost; } int kruskal(int n){ sort(e.begin(),e.end(),cmp); int max = 0; UFinit(n); for(int i = 0;i < e.size();i++){ if(Union(e[i].u,e[i].v)){ if(max<e[i].cost) max = e[i].cost; } } if(fcnt == 1) return max; else return -1; } int main(){ int T; scanf("%d",&T); while(--T!=-1){ int N; scanf("%d",&N); int mat[MAXN][MAXN]; for(int i = 0;i < N;i++){ for(int j = 0; j < N;j++){ scanf("%d",&mat[i][j]); } } for(int i = 0;i < N;i++){ for(int j = 0;j <= i;j++){ e.push_back(Edge(mat[i][j],i,j)); } } // for(int i = 0; i < e.size();i++) // printf("%d %d",e[i].u,e[i].v); printf("%d\n",kruskal(N)); e.clear(); } return 0; }
2092K 219MS