UVA--10600---ACM Contest and Blackout

In order to prepare the “The First National ACM School Contest” (in 20??) the major of the citydecided to provide all the schools with a reliable source of power. (The major is really afraid ofblackoutsJ). So, in order to do that, power station “Future” and one school (doesn’t matter which one)must be connected; in addition, some schools must be connected as well.

You may assume that a school has a reliable source of power if it’s connected directly to “Future”,or to any other school that has a reliable source of power. You are given the cost of connection betweensome schools. The major has decided to pick out two the cheapest connection plans – the cost of theconnection is equal to the sum of the connections between the schools. Your task is to help the major— find the cost of the two cheapest connection plans.

Input

The Input starts with the number of test cases, T (1 < T < 15) on a line. Then T test cases follow. Thefirst line of every test case contains two numbers, which are separated by a space, N (3 < N < 100)the number of schools in the city, and M the number of possible connections among them. Next Mlines contain three numbers Ai, Bi, Ci, where Ciis the cost of the connection (1 < Ci < 300) betweenschools Ai and Bi. The schools are numbered with integers in the range 1 to N.

Output

For every test case print only one line of output. This line should contain two numbers separated by asingle space – the cost of two the cheapest connection plans. Let S1 be the cheapest cost and S2 thenext cheapest cost. It’s important, that S1 = S2 if and only if there are two cheapest plans, otherwiseS1 < S2. You can assume that it is always possible to find the costs S1 and S2.
Sample Input
2
5 8
1 3 75
3 4 51
2 4 19
3 2 95
2 5 42
5 4 31
1 2 9
3 5 66
9 14
1 2 4
1 8 8
2 8 11
3 2 8
8 9 7
8 7 1
7 9 6
9 3 2
3 4 7
3 6 4
7 6 2
4 6 14
4 5 9
5 6 10
Sample Output
110 121
37 37

先求最小生成树,再求次级最优生成树。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<vector>
#include<map>
#include<cstring>
using namespace std;
#define min(a,b) ((a)>(b)?(b):(a))
#define MAX 1000000000
int UFS[108],in[108][108],n,m;
int UFS_find(int x)
{
    if(x!=UFS[x])
        UFS[x]=UFS_find(UFS[x]);
    return UFS[x];
}
void UFS_insert(int x,int y)
{
    x=UFS_find(x);
    y=UFS_find(y);
    UFS[max(x,y)]=min(x,y);
}
struct AP
{
    int x,y,value;
    bool operator <(const AP &a)const
    {
        return value>a.value;
    }
};
AP func1(int x,int y,int z)
{
    AP t;
    t.x=x;
    t.y=y;
    t.value=z;
    return t;
}
int main()
{
    int N;
    cin>>N;
    while(N--)
    {
        priority_queue<AP>que1;
        vector<AP>vec1;
        queue<AP>que3;
        memset(in,0,sizeof(in));
        cin>>n>>m;
        while(m--)
        {
            int x1,x2,x3;
            cin>>x1>>x2>>x3;
            if(x1!=x2)
            {
                in[x1][x2]=in[x2][x1]=x3;
                que1.push(func1(x1,x2,x3));
            }
        }
        for(int i=1; i<=n; i++)
            UFS[i]=i;
        int T=n-1,sum=0,ans=0;
        while(!que1.empty())
        {
            AP temp;
            temp=que1.top();
            que1.pop();
            if(UFS_find(temp.x)!=UFS_find(temp.y))
            {
                UFS_insert(temp.x,temp.y);
                vec1.push_back(temp);
                ans+=temp.value;
                sum++;
                if(T==sum)
                {
                    while(!que1.empty())
                    {
                        que3.push(que1.top());
                        que1.pop();
                    }
                    break;
                }
            }
            else
                que3.push(temp);
        }
        cout<<ans<<' ';
        int MIN=MAX;
        while(!que3.empty())
        {
            AP temp=que3.front();
            que3.pop();
            for(int i=1; i<=n; i++)
                UFS[i]=i;
            UFS[max(temp.x,temp.y)]=min(temp.y,temp.x);
            T=n-2;
            sum=0;
            ans=temp.value;
            vector<AP>::iterator it;
            for(it=vec1.begin(); it!=vec1.end(); it++)
                if(UFS_find((*it).x)!=UFS_find((*it).y))
                {
                    UFS_insert((*it).x,(*it).y);
                    ans+=(*it).value;
                    sum++;
                    if(T==sum)
                        break;
                }
            MIN=min(MIN,ans);
        }
        cout<<MIN<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值