LightOJ - 1040 Donation

Description

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.

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.

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 ithinteger 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

3

 

2

27 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

Sample Output

Case 1: 105

Case 2: 12

Case 3: -1


題解:最小生成樹,尋找多餘的電線,用總的減去最小生成樹的值

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

const int max_n = 3010;
int f[max_n];
int n,sum,len;

struct node{
    int u,v,cost;
}pic[max_n];

bool cmp(const node& n1,const node& n2){
    return n1.cost < n2.cost;
}

int find_(int x){
    return f[x] == x ? x:f[x]=find_(f[x]);
}

void MST(){
    if(n == 1){cout<<sum<<endl;return;}
    int ans = 0;
    int len2 = 0;
    sort(pic+1,pic+len+1,cmp);
    for(int i = 1; i <= n; i++)f[i] = i;
    for(int i = 0; i <= len; i++){
        int x1 = find_(pic[i].u);
        int x2 = find_(pic[i].v);
        if(x1!=x2){
            f[x1] = x2;
            ans += pic[i].cost;
            len2++;
        }
    }
    sum-=ans;
    len2!=n-1 ? cout<<-1<<endl:cout<<sum<<endl;
}

int main(){
    int T;
    cin>>T;
    for(int t = 1; t <= T;t++){
        cin>>n;
        int c;sum = 0;len = 1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                cin>>c;
                if(i==j)sum+=c;
                else if(c == 0)continue;
                else{
                    pic[len].u = i;
                    pic[len].v = j;
                    pic[len].cost = c;
                    len++;
                    sum+=c;
                }
            }
        }
        cout<<"Case "<<t<<": ";
        len--;
        MST();
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章