标签:
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