2015-01-04 14:19:46
学习是螺旋性的,今天来复习一下最小生成树的prim和kruskal,及prim堆优化。
采用 POJ 1258 作为测试平台。(题意:输入N,并输入N×N的点距离邻接矩阵,输入MST总长度)
First:Prim(适合稠密图,复杂度:朴素:O(V*V);堆优化:O(E*logV)(关于这个复杂度还没怎么想明白orz...))
思路回顾:prim是从一个只包含一个点的点集出发,不断找出从当前点集到其余点的最小权边,并添加最小权边的终点进点集,直至点集包含所有点。(可以看做点集扩张)
简证:如果在选当前点集X的出边时不选择最小权边(假设为e),而选择另一条边(假设为f)并构成生成树T,也就是说连接X和V-X的是边f,那么如果我们把e加入T,必定构成圈,再把f删掉,此时T-f+e仍然为生成树,又因为cost(f) >= cost(e),所以T-f+e <= T,所以选择e更合算,得证。
(1)朴素prim:
细节:总共找n-1条边,到各个点的距离用dis[]数组维护,已入点集的用used[]数组标记
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <iostream> 11 #include <algorithm> 12 using namespace std; 13 #define lp (p << 1) 14 #define rp (p << 1|1) 15 #define getmid(l,r) (l + (r - l) / 2) 16 #define MP(a,b) make_pair(a,b) 17 typedef long long ll; 18 typedef unsigned long long ull; 19 typedef pair<int,int> pii; 20 const int INF = (1 << 30) - 1; 21 const int maxn = 110; 22 23 int N; 24 struct edge{ 25 int v,cost; 26 }e[maxn * maxn]; 27 int first[maxn],next[maxn * maxn],ecnt; 28 int dis[maxn],used[maxn]; 29 30 void Add_edge(int u,int v,int c){ 31 next[++ecnt] = first[u]; 32 e[ecnt].v = v; 33 e[ecnt].cost = c; 34 first[u] = ecnt; 35 } 36 37 int Prim(){ 38 int p = 1,mst = 0; 39 memset(used,0,sizeof(used)); 40 fill(dis + 1,dis + N + 1,INF); 41 used[1] = 1; 42 for(int i = first[1]; i != -1; i = next[i]){ 43 dis[e[i].v] = e[i].cost; 44 } 45 for(int k = 1; k < N; ++k){ 46 int tmin = INF; 47 for(int i = 1; i <= N; ++i) 48 if(!used[i] && dis[i] < tmin) tmin = dis[p = i]; 49 mst += tmin; 50 used[p] = 1; 51 for(int i = first[p]; i != -1; i = next[i]){ 52 int v = e[i].v; 53 if(!used[v] && dis[v] > e[i].cost) 54 dis[v] = e[i].cost; 55 } 56 } 57 return mst; 58 } 59 60 int main(){ 61 int tmp; 62 while(scanf("%d",&N) != EOF){ 63 memset(first,-1,sizeof(first)); 64 ecnt = 0; 65 for(int i = 1; i <= N; ++i){ 66 for(int j = 1; j <= N; ++j){ 67 scanf("%d",&tmp); 68 if(tmp) Add_edge(i,j,tmp); 69 } 70 } 71 printf("%d\n",Prim()); 72 } 73 return 0; 74 }