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 ("?\n");
68         else printf ("%d\n", 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 ("?\n");
94         else printf ("%d\n", 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\n", 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\n", ans);
92     }
93     return 0;
94 }
View Code

 

posted @ 2013-12-01 02:44  Plumrain  阅读(384)  评论(0编辑  收藏  举报