UVa1151 Buy or Build

填坑(p.358)

以前天真的以为用prim把n-1条边求出来就可以

现在看来是我想多了

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 #include<iostream>
  6 
  7 const int N = 1000 + 10;
  8 
  9 struct Node {
 10     int x, y;
 11     Node(int x = 0, int y = 0) : x(x), y(y) {}
 12 }p[N];
 13 
 14 int sqr(int x) {
 15     return x * x;
 16 }
 17 
 18 int dist(const Node& a, const Node& b) {
 19     return sqr(a.x - b.x) + sqr(a.y - b.y);
 20 }
 21 
 22 struct Edge {
 23     int u, v, w;
 24     Edge() {}
 25     Edge(int u, int v, int w) : u(u), v(v), w(w) {}
 26     bool operator < (const Edge& rhs) const {
 27         return w < rhs.w;
 28     }
 29 };
 30 #include<vector>
 31 std::vector<Edge> edges, pree;
 32 
 33 int n, ans;
 34 int d[N], pre[N], dis[N][N];
 35 bool inMST[N];
 36 
 37 void prim() {
 38     memset(d, 0x3f, sizeof d);
 39     memset(inMST, 0, sizeof inMST);
 40     ans = d[0] = 0;
 41     for(int i = 0; i < n; i++) {
 42         int u = -1;
 43         for(int v = 0; v < n; v++) if(!inMST[v]) {
 44             if(u == -1 || d[v] < d[u]) u = v;
 45         }
 46         inMST[u] = 1;
 47         ans += d[u];
 48         if(i) edges.push_back(Edge(u, pre[u], dis[u][pre[u]]));
 49         for(int v = 0; v < n; v++) if(!inMST[v]) {
 50             if(d[v] > d[u] + dis[u][v]) {
 51                 d[v] = d[u] + dis[u][v];
 52                 pre[v] = u;
 53             }
 54         }
 55     }
 56 }
 57 
 58 int fa[N];
 59 int find(int x) {
 60     return fa[x] == x ? x : fa[x] = find(fa[x]);
 61 }
 62 
 63 bool merge(int x, int y) {
 64     x = find(x), y = find(y);
 65     if(x == y) return 0;
 66     return fa[x] = y, 1;
 67 }
 68 
 69 void UFS_init() {
 70     for(int i = 0; i < n; i++) fa[i] = i;
 71 }
 72 
 73 void pre_kruskal() {
 74     for(int i = 0; i < n; i++) {
 75         for(int j = i + 1; j < n; j++) {
 76             pree.push_back(Edge(i, j, dis[i][j]));
 77         }
 78     }
 79     sort(pree.begin(), pree.end());
 80     
 81     UFS_init();
 82     int MST = n;
 83     ans = 0;
 84     for(unsigned i = 0; i < pree.size(); i++) {
 85         const Edge& e = pree[i];
 86         if(merge(e.u, e.v)) {
 87             edges.push_back(e);
 88             ans += e.w;
 89             if(--MST == 1) break;
 90         }
 91     }
 92 }
 93 
 94 int q;
 95 #include<vector>
 96 std::vector<int> frees[10];
 97 int cost[10];
 98 #include<cassert>
 99 void Kruskal(int mask) {
100     UFS_init();
101     int MST = n, res = 0;
102     for(int j = 0; j < q; j++) if(mask >> j & 1) {
103         res += cost[j];
104         for(unsigned i = 1; i < frees[j].size(); i++) {
105             MST -= merge(frees[j][i-1], frees[j][i]);
106         }
107     }
108     
109     for(unsigned i = 0; i < edges.size(); i++) {
110         if(MST == 1) break;
111         if(merge(edges[i].u, edges[i].v)) res += edges[i].w, MST--;
112     }
113     assert(MST == 1);
114     ans = std::min(ans, res);
115 }
116 
117 int main() {
118 #ifdef DEBUG
119     freopen("in.txt", "r", stdin);
120     freopen("out.txt", "w", stdout);
121 #endif
122     
123     int T; scanf("%d", &T);
124     while(T--) {
125         pree.clear();
126         edges.clear();
127         scanf("%d%d", &n, &q);
128         for(int i = 0; i < q; i++) {
129             int m;
130             scanf("%d%d", &m, cost + i);
131             frees[i].resize(m);
132             for(int j = 0; j < m; j++) {
133                 scanf("%d", &frees[i][j]);
134                 --frees[i][j]; 
135             }
136         }
137         for(int i = 0; i < n; i++) {
138             scanf("%d%d", &p[i].x, &p[i].y);
139             for(int j = 0; j < i; j++) {
140                 dis[i][j] = dis[j][i] = dist(p[i], p[j]);
141             }
142         }
143         pre_kruskal();
144         std::sort(edges.begin(), edges.end());
145         for(int mask = 0; mask < (1 << q); mask++) {
146             Kruskal(mask);
147         }
148         
149         printf("%d
", ans);
150         if(T) puts("");
151     }
152     
153     return 0;
154 }
View Code
原文地址:https://www.cnblogs.com/showson/p/5113312.html