1040 - Donation
You will be given the lengths (in meters) of cables between each pair of rooms in your house. You wish to keep only enough cable so that every pair of rooms in your house is connected by some chain of cables, of any length. The lengths are given in n lines, each having n integers, where n is the number of rooms in your house. The jth integer of ith line gives the length of the cable between rooms i and j in your house.A local charity is trying to gather donations of Ethernet cable. You realize that you probably have a lot of extra cable in your house, and make the decision that you will donate as much cable as you can spare.
If both the jth integer of ith line and the ith integer of jth line are greater than 0, this means that you have two cables connecting rooms i and j, and you can certainly donate at least one of them. If the ith integer of ith line is greater than 0, this indicates unused cable in room i, which you can donate without affecting your home network in any way. 0 means no cable.
You are not to rearrange any cables in your house; you are only to remove unnecessary ones. Return the maximum total length of cables (in meters) that you can donate. If any pair of rooms is not initially connected by some path, return -1.
Input
Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case begins with a blank line and an integer n (1 ≤ n ≤ 50) denoting the number of rooms in your house. Then there will be n lines, each having n space separated integers, denoting the lengths as described. Each length will be between 0 and 100.
Output
For each case of input you have to print the case number and desired result.
Sample Input |
Output for Sample Input |
3227 26
1 52
4 0 10 10 0 0 0 1 1 0 0 0 2 0 0 0 0
4 0 1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 |
Case 1: 105Case 2: 12Case 3: -1 |
题目类型:MST
算法分析:使用kruskal算法计算最小生成树的权值和sum,然后直接使用总长度tot减去计算得到的sum,如果图不连通则直接输出-1
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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
#include <set> #include <bitset> #include <list> #include <map> #include <stack> #include <queue> #include <deque> #include <string> #include <vector> #include <ios> #include <iostream> #include <fstream> #include <sstream> #include <iomanip> #include <algorithm> #include <utility> #include <complex> #include <numeric> #include <functional> #include <cmath> #include <ctime> #include <climits> #include <cstdarg> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <cassert> #define lson rt << 1, l, m #define rson rt << 1 | 1, m + 1, r using namespace std; const int INF = 0x7FFFFFFF; const double EPS = 1e-10; const double PI = 2 * acos (0.0); const int MOD = 7; const int maxn = 166; struct Node { int u, v, w; }; Node edge[maxn*maxn]; int ans[maxn][maxn], len, parent[maxn], sum; int n; bool is_valid; void Init () { int i; for (i = 0; i < maxn; i++) parent[i] = i; } int UnFind (int val) { if (parent[val] == val) return val; return parent[val] = UnFind (parent[val]); } void kruskal () { is_valid = true; int i, remain = n; sum = 0; for (i = 0; i < len && remain > 1; i++) { if (UnFind (edge[i].u) != UnFind (edge[i].v) && edge[i].w) { parent[UnFind(edge[i].u)] = UnFind (edge[i].v); remain--; sum += edge[i].w; } } if (remain > 1) is_valid = false; } bool Cmp (Node a, Node b) { return a.w < b.w; } int main() { // ifstream cin ("aaa.txt"); int t, flag = 1; cin >> t; while (t--) { cout << "Case " << flag++ << ": "; Init (); cin >> n; int i, j, tot = 0; for (i = 0; i < n; i++) for (j = 0; j < n; j++) { cin >> ans[i][j]; tot += ans[i][j]; } len = 0; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { if (i == j) continue; edge[len].u = i; edge[len].v = j; edge[len++].w = ans[i][j]; } } sort (edge, edge + len, Cmp); kruskal (); if (is_valid) cout << tot - sum << endl; else cout << "-1" << endl; } return 0; } |
- « 上一篇:lightoj1035
- lightoj1041:下一篇 »