1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| #include <iostream> #include <algorithm> #include <cstdio> #include <vector> #include <cstring>
using namespace std;
typedef long long ll;
const int N = 2010; const int M = N * N;
struct node { int u, v; ll w; };
ll x[N], y[N], c[N], k[N]; int n, fa[N], tot, cnt1, cnt2; node edge[M]; int px[M], py[M], p[M];
void add_edge(int u, int v, ll w) { edge[tot].u = u; edge[tot].v = v; edge[tot++].w = w; }
bool cmp(const node a, const node b) { return a.w < b.w; }
int find(int x) { return -1 == fa[x] ? x : fa[x] = find(fa[x]); }
ll Kruskal(int n) { memset(fa, -1, sizeof(fa)); sort(edge, edge + tot, cmp); int cnt = 0; ll ans = 0; for (int i = 0; i < tot; i++) { int u = edge[i].u, v = edge[i].v; ll w = edge[i].w; int t1 = find(u), t2 = find(v); if (t1 != t2) { if (0 == u || 0 == v) p[++cnt1] = u + v; else px[++cnt2] = u, py[cnt2] = v; ans += w, fa[t1] = t2, cnt++; } if (cnt == n - 1) break; } if (cnt < n - 1) return -1; else return ans; }
int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%lld%lld", &x[i], &y[i]); for (int i = 1; i <= n; i++) scanf("%lld", &c[i]); for (int i = 1; i <= n; i++) scanf("%lld", &k[i]); for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (i != j) { ll w = (k[i] + k[j]) * (abs(x[i] - x[j]) + abs(y[i] - y[j])); add_edge(i, j, w); } } } for (int i = 1; i <= n; i++) { add_edge(0, i, c[i]); add_edge(i, 0, c[i]); } printf("%lld\n", Kruskal(n + 1)); printf("%d\n", cnt1); for (int i = 1; i <= cnt1; i++) { if (i == cnt1) printf("%d\n", p[i]); else printf("%d ", p[i]); } printf("%d\n", cnt2); for (int i = 1; i <= cnt2; i++) printf("%d %d\n", px[i], py[i]); return 0; }
|