链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3592
题意&题解:
紫书P358
代码:
31 int n, m; 32 VI v[10]; 33 PII p[MAXN]; 34 struct Edge { 35 int u, v, cost; 36 bool operator<(const Edge& t) { 37 return cost < t.cost; 38 } 39 }; 40 vector<Edge> E; 41 vector<Edge> E1; 42 int par[MAXN]; 43 44 int find(int x) { 45 return par[x] = par[x] == x ? x : find(par[x]); 46 } 47 48 void unite(int x, int y) { 49 int a = find(x), b = find(y); 50 if (a != b) par[a] = b; 51 } 52 53 int kruskal() { 54 sort(all(E)); 55 rep(i, 1, n + 1) par[i] = i; 56 int res = 0; 57 rep(i, 0, E.size()) { 58 Edge e = E[i]; 59 if (find(e.u) != find(e.v)) { 60 unite(e.u, e.v); 61 res += e.cost; 62 E1.pb(e); 63 } 64 } 65 return res; 66 } 67 68 int kruskal1() { 69 int res = 0; 70 rep(i, 0, E1.size()) { 71 Edge e = E1[i]; 72 if (find(e.u) != find(e.v)) { 73 unite(e.u, e.v); 74 res += e.cost; 75 } 76 } 77 return res; 78 } 79 80 void init() { 81 rep(i, 0, 10) v[i].clear(); 82 E.clear(); 83 E1.clear(); 84 } 85 86 int main() { 87 ios::sync_with_stdio(false), cin.tie(0); 88 int T; 89 cin >> T; 90 while (T--) { 91 init(); 92 cin >> n >> m; 93 rep(i, 0, m) { 94 int k; 95 cin >> k; 96 int x; 97 cin >> x; 98 v[i].pb(x); 99 while (k--) { 100 cin >> x; 101 v[i].pb(x); 102 } 103 } 104 rep(i, 1, n + 1) cin >> p[i].first >> p[i].second; 105 rep(i, 1, n + 1) rep(j, i + 1, n + 1) 106 E.pb(Edge{ i, j, (p[i].first - p[j].first)*(p[i].first - p[j].first) 107 + (p[i].second - p[j].second)*(p[i].second - p[j].second) }); 108 int ans = kruskal(); 109 rep(i, 0, 1 << m) { 110 rep(j, 1, n + 1) par[j] = j; 111 int sum = 0; 112 rep(j, 0, m) if (i&(1 << j)) { 113 sum += v[j][0]; 114 rep(k, 1, v[j].size()) unite(v[j][1], v[j][k]); 115 } 116 ans = min(ans, sum + kruskal1()); 117 } 118 cout << ans << endl; 119 if (T) cout << endl; 120 } 121 return 0; 122 }