wenbao與最小生成樹
阿新 • • 發佈:2018-04-14
val color \n AS spl memset 隊列優化 display esp
----------------------------------------------------------
Kruskal模板
1 const int maxn = 105; 2 int n, m, u[maxn], v[maxn], w[maxn], r[maxn], p[maxn]; 3 4 int cmp(const int i, const int j) { 5 return w[i] < w[j]; 6 } 7 8 int findn(int x) { 9 return p[x] == x ? x : p[x] = findn(p[x]);10 } 11 12 int Kruskal() { 13 int ans = 0, num = 0; 14 for(int i = 1; i <= m; ++i) p[i] = i; 15 sort(r, r+n, cmp); 16 for(int i = 0; i < n; i++) { 17 int e = r[i]; 18 int x = findn(u[e]), y = findn(v[e]); 19 if(x != y) { 20 num ++; 21 ans += w[e];22 p[x] = y; 23 } 24 } 25 if(num != m-1) printf("?\n"); 26 else printf("%d\n", ans); 27 }
離散課本實現
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 struct Node{ 5 int v, vv, w; 6 }T[20]; 7 int cmp(Node a, Node b){8 return a.w < b.w; 9 } 10 int TT[20]; 11 int Find(int x){ 12 return TT[x] == x ? x : TT[x] = Find(TT[x]); 13 } 14 void kru(int x){ 15 for(int i = 0; i <= x; i++){ 16 TT[i] = i; 17 } 18 int sum = 0; 19 sort(T, T+x, cmp); 20 for(int i = 0; i < x; i++){ 21 int xx = Find(T[i].v); 22 int yy = Find(T[i].vv); 23 if(xx != yy){ 24 sum += T[i].w; 25 TT[xx] = yy; 26 } 27 } 28 printf("%d\n", sum); 29 } 30 int main(){ 31 int n; 32 scanf("%d", &n); 33 for(int i = 0; i < n; i++){ 34 scanf("%d%d%d", &T[i].v, &T[i].vv, &T[i].w); 35 } 36 kru(n); 37 }
-------------------------------------------------------------------------
prim
鄰接表優化
1 int head[111], Next[222], point[222], val[222], size, dist[111]; 2 int n, m, x, y, z; 3 4 void add (int a, int b, int v) { 5 int i; 6 for(i = head[a]; ~i; i = Next[i]) { 7 if(point[i] == b) { 8 if(val[i] > v) val[i] = v; 9 return; 10 } 11 } 12 point[size] = b; 13 val[size] = v; 14 Next[size] = head[a]; 15 head[a] = size++; 16 } 17 18 void prim() { //prim函數,傳入圖中一點 19 memset(dist, 0x3f3f, sizeof(dist)); 20 for(int i = head[1]; ~i; i = Next[i]){ 21 dist[point[i]] = val[i]; 22 } 23 dist[1] = -1; 24 int sum = 0; 25 for(int i = 2; i <= m; ++i){ 26 int mi = 1e9, k = -1; 27 for(int j = 2; j <= m; ++j){ 28 if(dist[j] != -1 && dist[j] < mi){ 29 mi = dist[j], k = j; 30 } 31 } 32 if(k == -1){ 33 printf("?\n"); 34 return ; 35 } 36 dist[k] = -1; 37 sum += mi; 38 for(int j = head[k]; ~j; j = Next[j]){ 39 if(dist[point[j]] != -1 && dist[point[j]] > val[j]){ 40 dist[point[j]] = val[j]; 41 } 42 } 43 } 44 printf("%d\n", sum); 45 }
鄰接表優先隊列優化
1 typedef pair<int,int> pii; 2 3 int head[30], next[200], point[200], val[200], size, dist[30]; 4 5 void add (int a, int b, int v) { //加邊及去重 6 int i; 7 for(i = head[a]; ~i; i = next[i]) { 8 if(point[i] == b) { 9 if(val[i] > v) val[i] = v; 10 return; 11 } 12 } 13 point[size] = b; 14 val[size] = v; 15 next[size] = head[a]; 16 head[a] = size++; 17 } 18 19 struct cmp { //重載小根堆 20 bool operator()(pii a, pii b) { 21 return a.first > b.first; 22 } 23 }; 24 25 void prim(int s) { //prim函數,傳入圖中一點 26 int i, ans = 0; 27 memset(dist, 0x3f, sizeof(dist)); 28 priority_queue<pii, vector<pii>, cmp>q; 29 for (i = head[s]; ~i; i = next[i]) { 30 dist[point[i]] = val[i]; 31 q.push(make_pair(dist[point[i]], point[i])); 32 } 33 dist[s] = -1; 34 while(!q.empty()) { 35 pii u = q.top(); 36 q.pop(); 37 if(dist[u.second] == -1) continue; 38 dist[u.second] = -1; 39 ans += u.first; 40 for(i = head[u.second]; ~i; i = next[i]) { 41 int j = point[i]; 42 if(dist[j] > val[i]) { 43 dist[j] = val[i]; 44 q.push(make_pair(dist[j], j)); 45 } 46 } 47 } 48 printf("%d\n", ans); 49 }
---------------------------------------------------------------------------
http://acm.hdu.edu.cn/showproblem.php?pid=1863
prim
1 #include "iostream" 2 #include <algorithm> 3 #include <string.h> 4 #include <queue> 5 #include <stdio.h> 6 using namespace std; 7 typedef pair<int,int> pii; 8 9 int head[111], Next[222], point[222], val[222], size, dist[111]; 10 bool vis[111]; 11 int n, m, x, y, z; 12 13 void add (int a, int b, int v) { //加邊及去重 14 int i; 15 for(i = head[a]; ~i; i = Next[i]) { 16 if(point[i] == b) { 17 if(val[i] > v) val[i] = v; 18 return; 19 } 20 } 21 point[size] = b; 22 val[size] = v; 23 Next[size] = head[a]; 24 head[a] = size++; 25 } 26 27 struct cmp { //重載小根堆 28 bool operator()(pii a, pii b) { 29 return a.first > b.first; 30 } 31 }; 32 33 void prim(int s) { //prim函數,傳入圖中一點 34 int i, ans = 0, num = 0; 35 memset(dist, -1, sizeof(dist)); 36 memset(vis, 0, sizeof(vis)); 37 priority_queue<pii, vector<pii>, cmp>q; 38 for (i = head[s]; ~i; i = Next[i]) { 39 dist[point[i]] = val[i]; 40 q.push(make_pair(dist[point[i]], point[i])); 41 } 42 dist[s] = 0; 43 vis[s] = 1; 44 while(!q.empty()) { 45 pii u = q.top(); 46 q.pop(); 47 if(vis[u.second]) continue; 48 vis[u.second] = 1; 49 ans += u.first; 50 num++; 51 for(i = head[u.second]; ~i; i = Next[i]) { 52 int j = point[i]; 53 if(!vis[j] && (dist[j] > val[i] || dist[j] == -1)) { 54 dist[j] = val[i]; 55 q.push(make_pair(dist[j], j)); 56 } 57 } 58 } 59 if(num != m-1) printf("?\n"); 60 else printf("%d\n", ans); 61 } 62 63 int main(){ 64 #ifdef wenbao 65 freopen("in", "r", stdin); 66 #endif 67 while(~scanf("%d%d", &n, &m)){ 68 if(n == 0) break; 69 size = 0; 70 memset(head, -1, sizeof(head)); 71 for(int i = 0; i < n; ++i){ 72 scanf("%d%d%d", &x, &y, &z); 73 add(x, y, z), add(y, x, z); 74 } 75 prim(1); 76 } 77 return 0; 78 }
Kruskal
1 #include "iostream" 2 #include <algorithm> 3 using namespace std; 4 5 const int maxn = 105; 6 int n, m, u[maxn], v[maxn], w[maxn], r[maxn], p[maxn]; 7 8 int cmp(const int i, const int j) { 9 return w[i] < w[j]; 10 } 11 12 int findn(int x) { 13 return p[x] == x ? x : p[x] = findn(p[x]); 14 } 15 16 int Kruskal() { 17 int ans = 0, num = 0; 18 for(int i = 1; i <= m; ++i) p[i] = i; 19 sort(r, r+n, cmp); 20 for(int i = 0; i < n; i++) { 21 int e = r[i]; 22 int x = findn(u[e]); 23 int y = findn(v[e]); 24 if(x != y) { 25 num ++; 26 ans += w[e]; 27 p[x] = y; 28 } 29 } 30 if(num != m-1) printf("?\n"); 31 else printf("%d\n", ans); 32 } 33 34 int main() { 35 #ifdef wenbao 36 freopen("in", "r", stdin); 37 #endif 38 while(~scanf("%d%d", &n, &m)){ 39 if(n == 0) break; 40 for(int i = 0; i < n; ++i){ 41 scanf("%d%d%d", &u[i], &v[i], &w[i]), r[i] = i; 42 } 43 Kruskal(); 44 } 45 return 0; 46 }
---------------------------------------------------------------------------
只有不斷學習才能進步!
wenbao與最小生成樹