Test instructions: There are n points on the plane (1<=n<=1000), your task is to have all n points connected, for this, you can create some new edges, the cost equals two endpoints of the Euclidean distance squared. There is also a Q (0<=q<=8) package that can be purchased, and if you purchase the I package, all the nodes in the package become interconnected, and the cost of the first package is CI.
Kruskal:
First, the smallest spanning tree of the original image is obtained, then the n-1 edge is given, and then after each time the package is enumerated, only the Bien Hoa in the package is considered n-1, then the minimum spanning tree is evaluated after the package is enumerated.
Key
In the Kruskal algorithm, the edges that already belong to the same connected component on both ends are no longer added to the spanning tree.
Then after the purchase of the package, the equivalent of some side of the contingency of 0, and for each side not in the package E, the order before e on the side of one also no less, but may be more than a few weights to 0 of the edge.
So the side that was thrown away when the original was Kruskal, and the Kruskal after the purchase of the package, would be thrown away.
#include <cstdio>#include<iostream>#include<sstream>#include<cmath>#include<cstring>#include<cstdlib>#include<string>#include<vector>#include<map>#include<Set>#include<queue>#include<stack>#include<algorithm>using namespacestd;#definell int#define_cle (M, a) memset (M, A, sizeof (m))#defineRepu (I, A, b) for (int i = A; I < b; i++)#defineREPD (I, A, b) for (int i = b; i >= A; i--)#defineSFI (n) scanf ("%d", &n)#definePFI (n) printf ("%d\n", N)#defineSfi2 (n, m) scanf ("%d%d", &n, &m)#defineSFD2 (n, m) scanf ("%lf%lf", &n, &m)#definePfi2 (n, m) printf ("%d%d\n", N, m)#definePfi3 (A, B, c) printf ("%d%d%d\n", A, B, c)Const intINF =0x3f3f3f3f;#defineMAXN 1010#defineMAXM 1500010ll W[MAXM];intm;intR[MAXM];intU[MAXM], V[MAXM], P[maxn];ll XX[MAXN], YY[MAXN];intKb[maxn];vector<int> f[9];intN, Q, num[9];intc[9];intcmpConst intIConst intj) { returnW[i] <w[j];}intFind (intx) { returnP[X] = = x? X:P[X] =Find (p[x]);} ll Kruskal1 () {ll ans=0; intLen =0; Repu (i,0, M) { intE =R[i]; intx =Find (U[e]); inty =Find (V[e]); if(X! =y) {Kb[len++] =e; Ans+=W[e]; P[X]=y; } } returnans;} ll Kruskal2 () {ll ans=0; intLen =0; intt = n-1; Repu (i,0N1) { intE =Kb[i]; intx =Find (U[e]); inty =Find (V[e]); if(X! =y) {ans+=W[e]; P[X]=y; } } returnans;}intMain () {intT; SFI (T); while(t--) {sfi2 (n, Q); M=0; Repu (i,0, Q) { intA; Sfi2 (Num[i], c[i]); F[i].clear (); Repu (J,0, Num[i]) SFI (a), F[i].push_back (a); } Repu (I,1, n +1) scanf ("%d%d", &xx[i], &Yy[i]); Repu (i,1, n +1) Repu (J,1+ I, n +1) {W[m]= (Xx[i]-xx[j]) * (Xx[i]-xx[j]) + (Yy[i]-yy[j]) * (Yy[i]-Yy[j]); U[M]=i; V[M]=J; //printf ("%d%d%d%lf\n", M, I, J, W[m]);m++; } Repu (I,1, n +1) P[i] =i; Repu (i,0, m) R[i] =i; Sort (R, R+m, CMP); LL Minn=Kruskal1 (); Sort (KB, KB+ N-1, CMP); //printf ("%lld\n", Minn); intLim =1<<Q; ll cc; Repu (i,1, Lim) {CC=0; Repu (J,1, n +1) P[j] =J; Repu (J,0, q)if((1<<J) &i)if(Num[j]) {cc+=C[j]; intx = Find (f[j][0]); Repu (k,1, Num[j]) { inty =Find (F[j][k]); if(x! = y) P[y] =x; } //printf ("%d%d\n", I, j);} Minn= MIN (minn, CC +Kruskal2 ()); //printf ("%lld\n", Minn);} printf ("%d\n", Minn); if(T) puts (""); } return 0;}
View Code
UVa 1151 (minimum spanning tree, enumeration subset)