A very good minimum spanning tree topic. Seemingly very complex, in fact, careful analysis of the complexity of the algorithm will find that if added Lrj said optimization, in fact, the complexity is not high.
As the purple book says, except for the points in the purchase package, the remaining minimum edges remain in the original minimum spanning tree. So we use the binary enumeration subset method to enumerate the combinations of all the purchase packages, then add the points in the plan to the collection, and then complement the current spanning tree with the edges in the original smallest spanning tree.
The complexity of a binary enumeration subset is 2^8. The complexity of the completion spanning tree is O (n). So the final complexity is O (n (2^8)), approximately equal to 10^6, acceptable.
There is a place I do not know is not a pit Ah, the topic clearly said that the Euclidean distance between two points of the square is the cost, but this is not a floating point? Why is it right to receive this value with int? A friend who wants to know the answer can advise.
See the code for details:
#include <bits/stdc++.h>using namespace Std;const int maxn = + 5;const int maxm = maxn* (MAXN); int T,N,M,REC,Q,CN T,PAR[MAXN], x[maxn],y[maxn];struct node {int N,C,A[MAXN];} p[9];struct edge{int A, b; int v;} Ed[maxm],e[maxn];bool cmp (Edge A,edge b) {return A.V < B.V;} int find (int x) {return par[x] = = x X:par[x] = find (Par[x]);} int solve () {for (int i=1;i<=n;i++) par[i] = i; Sort (ed,ed+cnt,cmp); int res = 1, ans = 0; rec = 0; for (int i=0;i<cnt;i++) {//Take out the edge set of the original minimum spanning tree int x = Find (ed[i].a), y = find (ed[i].b); if (x! = y) {ans + = ED[I].V; E[REC].A = ED[I].A; e[rec].b = ed[i].b; E[REC++].V = ED[I].V; Par[x] = y; res++; } if (res = = n) break; } for (int s=0;s< (1<<Q); s++) {//binary enumeration of possible scenarios for all packages for (int j=1;j<=n;j++) par[j] = j; Initialize and check set int cur = 0; for (int j=0;j<q;j++) {if (S & (1<<j)) { Cur + = p[j].c; for (int i=1;i<=p[j].n;i++) {int x = find (P[j].a[i]), y = Find (p[j].a[1]); if (x! = y) par[x] = y; }}} for (int i=0;i<rec;i++) {//padding int x = find (e[i].a), y = find (e[i].b); if (x! = y) {cur + = E[I].V; Par[x] = y; }} ans = min (ans,cur); Update} return ans; int main () {scanf ("%d", &t); while (t--) {scanf ("%d%d", &n,&q); for (int i=0;i<q;i++) {scanf ("%d%d", &p[i].n,&p[i].c); for (int j=1;j<=p[i].n;j++) scanf ("%d", &p[i].a[j]); } for (int i=1;i<=n;i++) scanf ("%d%d", &x[i],&y[i]); CNT = 0; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) {int v = (X[i]-x[j]) * (X[i]-x[j]) + (Y[i]-y[j] ) * (Y[i]-y[j]); ED[CNT].A = i; ED[CNT].B = J ED[CNT++].V = v; } printf ("%d\n", Solve ()); if (T) printf ("\ n"); } return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
1151-buy or build (minimum spanning tree)