Question:
N points x y z (point mark starts from 1)
Coordinates of the following n points (3D)
Line I below indicates that point I can direct traffic to Point u.
Water is required for n villages
1. Self-drilling, cost: coordinate height X
2. Traffic is diverted from a well-built village, and the cost is: the distance from Manhattan * Y (if the water is flowing to a height, it will also take Z to buy a water pump)
3. Assume that at the beginning all villages did not have any wells or pipelines.
Q:
If everyone can use water, the minimum cost is output; otherwise, the poor XiaoA is output.
Ideas:
Because drainage must start from a village where wells exist, the virtual root 0 is built and connected to each village. the edge right is the cost of drilling wells.
Then run the minimum tree structure.
# Include
# Include
# Include
# Include
Using namespace std;/** minimum tree structure * complexity O (NM) * points starting from 0 */const int INF = 100000000; const int MAXN = 1010; // point const int MAXM = 1010000; // number of sides # define ll intstruct Edge {int u, v; ll cost;} edge [MAXM]; // int pre [MAXN], id [MAXN], visit [MAXN]; ll in [MAXN]; ll zhuliu (int root, int n, int m, edge edge []) // Number of edges of any starting point edge {int u, v; ll res = 0; while (1) {for (int I = 0; I <n; I ++) in [I] = INF; for (int I = 0; I <m; I ++) if (edge [I]. u! = Edge [I]. v & edge [I]. cost <in [edge [I]. v]) {pre [edge [I]. v] = edge [I]. u; in [edge [I]. v] = edge [I]. cost;} int tn = 0; memset (id,-1, sizeof (id); memset (visit,-1, sizeof (visit )); in [root] = 0; for (int I = 0; I <n; I ++) {res + = in [I]; v = I; while (visit [v]! = I & id [v] =-1 & v! = Root) {visit [v] = I; v = pre [v];} if (v! = Root & id [v] =-1) {for (int u = pre [v]; u! = V; u = pre [u]) id [u] = tn; id [v] = tn ++;} if (tn = 0) break; // No directed ring for (int I = 0; I <n; I ++) if (id [I] =-1) id [I] = tn ++; for (int I = 0; I <m;) {v = edge [I]. v; edge [I]. u = id [edge [I]. u]; edge [I]. v = id [edge [I]. v]; if (edge [I]. u! = Edge [I]. v) edge [I ++]. cost-= in [v]; elseswap (edge [I], edge [-- m]);} n = tn; root = id [root];} return res ;} struct node {ll a, B, c;} p [MAXN]; ll Dis (node a, node B) {return abs (. a-b.a) + abs (. b-b. B) + abs (. c-b.c);} int n; ll X, Y, Z; int main () {int I, j, k, u; while (scanf ("% d", & n, & X, & Y, & Z), n + X + Y + Z) {for (I = 1; I <= n; I ++) {scanf ("% d", & p [I]. a, & p [I]. b, & p [I]. c);} int edgenum = 0; for (I = 1; I <= n; I ++) {scanf ("% d", & k ); edge E = {0, I, p [I]. c * X}; edge [edgenum ++] = E; while (k --) {scanf ("% d", & u); if (u = I) continue; ll cost = Dis (p [I], p [u]) * Y; if (p [u]. c> p [I]. c) cost + = Z; Edge E2 = {I, u, cost}; edge [edgenum ++] = E2 ;}} printf ("% d \ n ", zhuliu (0, n + 1, edgenum, edge);} return 0;}/* 2 10 20 301 3 22 4 11 22 1 20 0 0 0 */