zoukankan      html  css  js  c++  java
  • HDU 畅通工程系列

    畅通工程系列都是比较裸的最小生成树问题,且是中文题目,不赘述了。

    1、HDU 1863 畅通工程

    题意:一个省有很多村庄,其中一些之间是可以建公路的,每条公路都需要不同的代价,问代价最小的情况下将所有村庄都连通。

    解法:裸的最小生成树。

    tag:MST

    由于才学MST,两种算法一个写了一遍:

    Kruskal:

     1 /*
     2  * Author:  Plumrain
     3  * Created Time:  2013-11-30 10:21
     4  * File Name: G-HDU-1863.cpp
     5  */
     6 #include <iostream>
     7 #include <cstdio>
     8 #include <algorithm>
     9 
    10 using namespace std;
    11 
    12 typedef pair<int, int> pii;
    13 struct Pat{
    14     int s, e, w;
    15 };
    16 
    17 int n, m, f[110];
    18 Pat p[10005];
    19 
    20 bool cmp(Pat a, Pat b)
    21 {
    22     return a.w < b.w;
    23 }
    24 
    25 void init()
    26 {
    27     for (int i = 0; i < n; ++ i){
    28         scanf ("%d%d%d", &p[i].s, &p[i].e, &p[i].w);
    29         -- p[i].s; --p[i].e;
    30     }
    31 }
    32 
    33 int find(int x)
    34 {
    35     if (x != f[x]) f[x] = find(f[x]);
    36     return f[x];
    37 }
    38 
    39 int kruskal(int n, int m)
    40 {
    41     sort(p, p+m, cmp);
    42     for (int i = 0; i < n; ++ i)
    43         f[i] = i;
    44     int cost = 0;
    45     for (int i = 0; i < m; ++ i){
    46         int s = p[i].s, e = p[i].e;
    47         int t1 = find(s), t2 = find(e);
    48         if (t1 != t2){
    49             f[t1] = t2;
    50             cost += p[i].w;
    51         }
    52     }
    53 
    54     int tmp = find(0);
    55     for (int i = 1; i < n; ++ i){
    56         find (i);
    57         if (f[i] != tmp) return -1;
    58     }
    59     return cost;
    60 }
    61 
    62 int main()
    63 {
    64     while (scanf ("%d%d", &n, &m) != EOF && n){
    65         init();
    66         int ans = kruskal(m, n);
    67         if (ans == -1) printf ("?
    ");
    68         else printf ("%d
    ", ans);
    69     }
    70     return 0;
    71 }
    View Code

    Prim:

     1 /*
     2  * Author:  Plumrain
     3  * Created Time:  2013-11-30 10:51
     4  * File Name: G-HDU-1863.cpp
     5  */
     6 #include <iostream>
     7 #include <cstdio>
     8 #include <cstring>
     9 #include <vector>
    10 #include <queue>
    11 #include <utility>
    12 
    13 using namespace std;
    14 
    15 #define CLR(x) memset(x, 0, sizeof(x))
    16 #define PB push_back
    17 const int maxint = 2147483647;
    18 typedef pair<int, int> pii;
    19 
    20 int n, m;
    21 bool v[110];
    22 int c[110];
    23 vector<pii> p[110];
    24 
    25 struct cmp{
    26     bool operator() (pii a, pii b){
    27         return a.second > b.second;
    28     }
    29 };
    30 
    31 void init()
    32 {
    33     for (int i = 0; i < n; ++ i)
    34         p[i].clear();
    35 
    36     int a, b, w;
    37     for (int i = 0; i < m; ++ i){
    38         scanf ("%d%d%d", &a, &b, &w);
    39         -- a; -- b;
    40         p[a].PB (make_pair(b, w));
    41         p[b].PB (make_pair(a, w));
    42     }
    43 }
    44 
    45 int prim(int n, int m)
    46 {
    47     int cost = 0;
    48     CLR (v);
    49     priority_queue<pii, vector<pii>, cmp> q;
    50     while (!q.empty()) q.pop();
    51 
    52     for (int i = 1; i < n; ++ i)
    53         c[i] = maxint - 1000;
    54     c[0] = 0;
    55     v[0] = 1;
    56     for (int i = 0; i < (int)p[0].size(); ++ i){
    57         pii tmp = p[0][i];
    58         c[tmp.first] = tmp.second;
    59         q.push (make_pair(tmp.first, tmp.second));
    60     }
    61 
    62     for (int i = 0; i < n-1; ++ i){
    63         if (q.empty()) break;
    64         pii tmp = q.top(); q.pop();
    65         while (v[tmp.first] && !q.empty()){
    66             tmp = q.top(); q.pop();
    67         }
    68         if (v[tmp.first]) break;
    69 
    70         int t1 = tmp.first, t2 = tmp.second;
    71         cost += t2;
    72         v[t1] = 1;
    73         c[t1] = 0;
    74         for (int j = 0; j < (int)p[t1].size(); ++ j) if (!v[p[t1][j].first]){
    75             pii t = p[t1][j];
    76             if (c[t.first] > t.second){
    77                 q.push (make_pair(t.first, t.second));
    78                 c[t.first] = t.second;
    79             }
    80         }
    81     }
    82 
    83     for (int i = 0; i < n; ++ i)
    84         if (!v[i]) return -1;
    85     return cost;
    86 }
    87 
    88 int main()
    89 {
    90     while (scanf ("%d%d", &m, &n) != EOF && m){
    91         init();
    92         int ans = prim(n, m);
    93         if (ans == -1) printf ("?
    ");
    94         else printf ("%d
    ", ans);
    95     }
    96     return 0;
    97 }
    View Code

    2、HDU 1875 畅通工程再续

    没写代码。

    3、HDU 1879 继续畅通工程

    用Kruskal写了一份:

     1 /*
     2  * Author:  Plumrain
     3  * Created Time:  2013-12-01 02:52
     4  * File Name: G-HDU-1879.cpp
     5  */
     6 #include <iostream>
     7 #include <cstdio>
     8 #include <algorithm>
     9 
    10 using namespace std;
    11 
    12 struct Pat{
    13     int s, e, w;
    14 };
    15 
    16 int n, all, f[110];
    17 Pat p[10005];
    18 
    19 bool cmp(Pat a, Pat b)
    20 {
    21     return a.w < b.w;
    22 }
    23 
    24 int find (int x)
    25 {
    26     if (x != f[x]) f[x] = find(f[x]);
    27     return f[x];
    28 }
    29 
    30 void init()
    31 {
    32     all = 0;
    33     for (int i = 0; i < n; ++ i)
    34         f[i] = i;
    35 
    36     int s, e, w, x;
    37     for (int i = 0; i < n*(n-1)/2; ++ i){
    38         scanf ("%d%d%d%d", &s, &e, &w, &x);
    39         -- s; -- e;
    40         if (x == 1){
    41             int t1 = find(s), t2 = find(e);
    42             if (t1 != t2) f[t1] = t2;
    43         }
    44         else{
    45             p[all].s = s; p[all].e = e;
    46             p[all++].w = w;
    47         }
    48     }
    49 }
    50 
    51 int kruskal()
    52 {
    53     int cost = 0;
    54     sort(p, p+all, cmp);
    55     for (int i = 0; i < all; ++ i){
    56         int s = p[i].s, e = p[i].e, w = p[i].w;
    57         int t1 = find(s), t2 = find(e);
    58         if (t1 != t2){
    59             f[t1] = t2; cost += w;
    60         }
    61     }
    62     return cost;
    63 }
    64 
    65 int main()
    66 {
    67     while (scanf ("%d", &n) != EOF && n){ 
    68         init();
    69         int ans = kruskal();
    70         printf ("%d
    ", ans);
    71     }
    72     return 0;
    73 }
    View Code

    4、HDU 1233 还是畅通工程

    用Prim写了一份:

     1 /*
     2  * Author:  Plumrain
     3  * Created Time:  2013-12-02 01:43
     4  * File Name: G-HDU-1233.cpp
     5  */
     6 #include <iostream>
     7 #include <cstdio>
     8 #include <cstring>
     9 #include <algorithm>
    10 #include <vector>
    11 #include <queue>
    12 #include <utility>
    13 
    14 using namespace std;
    15 
    16 #define CLR(x) memset(x, 0, sizeof(x))
    17 #define CLR1(x) memset(x, -1, sizeof(x))
    18 #define PB push_back
    19 typedef pair<int, int> pii;
    20 
    21 int n, m, d[110];
    22 bool v[110];
    23 vector<pii> pat[110];
    24 
    25 struct cmp{
    26     bool operator() (pii a, pii b){
    27         return a.second > b.second;
    28     }
    29 };
    30 
    31 void init()
    32 {
    33     for (int i = 0; i < n; ++ i)
    34         pat[i].clear();
    35 
    36     m = n * (n-1) / 2;
    37     int a, b, w;
    38     for (int i = 0; i < m; ++ i){
    39         scanf ("%d%d%d", &a, &b, &w);
    40         -- a; -- b;
    41         pat[a].PB (make_pair(b, w));
    42         pat[b].PB (make_pair(a, w));
    43     }
    44 }
    45 
    46 int Prim(int n, int m)
    47 {
    48     priority_queue<pii, vector<pii>, cmp> q;
    49     while (!q.empty()) q.pop();
    50 
    51     int cost = 0;
    52     CLR1 (d);
    53     CLR (v); v[0] = 1; d[0] = 0;
    54     int t_sz = pat[0].size();
    55     for (int i = 0; i < t_sz; ++ i){
    56         pii tmp = pat[0][i];
    57         d[tmp.first] = tmp.second;
    58         q.push (tmp);
    59     }
    60 
    61     for (int i = 0; i < n-1; ++ i){
    62         if (q.empty()) break;
    63         pii tmp = q.top(); q.pop();
    64         while (v[tmp.first] && !q.empty()){
    65             tmp = q.top(); q.pop();
    66         }
    67         if (v[tmp.first]) break;
    68 
    69         int t1 = tmp.first, t2 = tmp.second;
    70         cost += t2; v[t1] = 1; d[t1] = 0;
    71         int sz = pat[t1].size();
    72         for (int j = 0; j < sz; ++ j) if (!v[pat[t1][j].first]){
    73             pii tt = pat[t1][j];
    74             if (d[tt.first] > tt.second){
    75                 q.push (make_pair(tt.first, tt.second));
    76                 d[tt.first] = tt.second;
    77             }
    78         }
    79     }
    80 
    81     for (int i = 0; i < n; ++ i)
    82         if (!v[i]) return -1;
    83     return cost;
    84 }
    85 
    86 int main()
    87 {
    88     while (scanf ("%d", &n) != EOF && n){
    89         init();
    90         int ans = Prim(n, m);
    91         printf ("%d
    ", ans);
    92     }
    93     return 0;
    94 }
    View Code
    ------------------------------------------------------------------
    现在的你,在干什么呢?
    你是不是还记得,你说你想成为岩哥那样的人。
  • 相关阅读:
    1014 Waiting in Line (30)(30 point(s))
    1013 Battle Over Cities (25)(25 point(s))
    1012 The Best Rank (25)(25 point(s))
    1011 World Cup Betting (20)(20 point(s))
    1010 Radix (25)(25 point(s))
    1009 Product of Polynomials (25)(25 point(s))
    1008 Elevator (20)(20 point(s))
    1007 Maximum Subsequence Sum (25)(25 point(s))
    1006 Sign In and Sign Out (25)(25 point(s))
    1005 Spell It Right (20)(20 point(s))
  • 原文地址:https://www.cnblogs.com/plumrain/p/HDU_changtong.html
Copyright © 2011-2022 走看看