标签:
2 10 20 30 1 3 2 2 4 1 1 2 2 1 2 0 0 0 0
30HintIn 3‐dimensional space Manhattan distance of point A (x1, y1, z1) and B(x2, y2, z2) is |x2‐x1|+|y2‐y1|+|z2‐z1|.
/************************************************************************* > File Name: hdu4009.cpp > Author: ALex > Mail: 405045132@qq.com > Created Time: 2015年01月26日 星期一 15时49分37秒 ************************************************************************/ #include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int inf = 0x3f3f3f3f; const int N = 1200; struct CITY { int x, y, z; }city[N]; struct node { int u, v, w; }edge[N * N + 10]; int pre[N], in[N], vis[N], id[N]; int zhuliu (int root, int n, int m) { int res = 0, u, v; while (1) { memset (in, inf, sizeof(in)); for (int i = 0; i < m; ++i) { if (edge[i].u != edge[i].v && edge[i].w < in[edge[i].v]) //忽略自环,寻找当前图每个点最短入边 { in[edge[i].v] = edge[i].w; pre[edge[i].v] = edge[i].u; } } for (int i = 0; i < n; ++i) { if (i != root && in[i] == inf) { return -1; //某点不可达(非root) } } int tn = 0; memset (id, -1, sizeof(id)); memset (vis, -1, sizeof(vis)); in[root] = 0; for (int i = 0; i < n; ++i) { res += in[i]; v = i; while (vis[v] != i && id[v] == -1 && v != root) //找有向环 { vis[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; } for (int i = 0; i < n; ++i) { if (id[i] == -1) { id[i] = tn++; } } for (int i = 0; i < m; ++i) //重新构图 { int 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].w -= in[v]; //权值变为增量(“破环付出的代价”) } } n = tn; root = id[root]; } return res; } int dist (int i, int j) { return abs (city[i].x - city[j].x) + abs(city[i].y - city[j].y) + abs(city[i].z - city[j].z); } int main () { int n, x, y, z, num, cnt; while (~scanf("%d%d%d%d", &n, &x, &y, &z)) { if (n == 0 && x == 0 && y == 0 && z == 0) { break; } for (int i = 1; i <= n; ++i) { scanf("%d%d%d", &city[i].x, &city[i].y, &city[i].z); } num = cnt = 0; int j; for (int i = 1; i <= n; ++i) { scanf("%d", &num); while (num--) { scanf("%d", &j); edge[cnt].u = i; edge[cnt].v = j; edge[cnt].w = dist (i, j) * y; if (city[i].z < city[j].z) { edge[cnt].w += z; } ++cnt; } } for (int i = 1; i <= n; ++i) { edge[cnt].u = 0; edge[cnt].v = i; edge[cnt++].w = city[i].z * x; } int ans = zhuliu (0, n + 1, cnt); if (ans == -1) { printf("poor XiaoA\n"); } else { printf("%d\n", ans); } } return 0; }
标签:
原文地址:http://blog.csdn.net/guard_mine/article/details/43153855