zoukankan      html  css  js  c++  java
  • wenbao与最小生成树

     ----------------------------------------------------------

    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("?
    ");
    26     else printf("%d
    ", 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
    ", 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("?
    ");
    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
    ", 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
    ", 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("?
    ");
    60     else printf("%d
    ", 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("?
    ");
    31     else printf("%d
    ", 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 }

     ---------------------------------------------------------------------------

    只有不断学习才能进步!

  • 相关阅读:
    Yslow的A评级指南
    Sqlserver 数据库自动备份
    他们如果什么也没有做,那将是我来世上的最大遗憾。
    规划人生
    安装程序无法复制一个或多个文件。特定错误码是0x4b8。
    Sqlserver数据库的恢复
    Android新手之旅(3) 信息的输出
    PDF开发控件
    通过快盘搭建自己的svn服务器
    Android新手之旅(2) 新手问题
  • 原文地址:https://www.cnblogs.com/wenbao/p/6225494.html
Copyright © 2011-2022 走看看