In order to prepare the “The First National ACM School Contest” (in 20??) the major of the city
decided to provide all the schools with a reliable source of power. (The major is really afraid of
blackoutsJ). 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 between
some schools. The major has decided to pick out two the cheapest connection plans – the cost of the
connection 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. The
first 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 M
lines contain three numbers Ai
, Bi
, Ci
, where Ci
is the cost of the connection (1 < Ci < 300) between
schools 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 a
single space – the cost of two the cheapest connection plans. Let S1 be the cheapest cost and S2 the
next cheapest cost. It’s important, that S1 = S2 if and only if there are two cheapest plans, otherwise
S1 < 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 <cmath>
#include <cstring>
#include <algorithm>
#define maxn 105
using namespace std;
const int inf=0x3f3f3f3f3f;
int maxe[maxn][maxn];
int used[maxn][maxn];
int n,m;
int pre[maxn];
int map[maxn][maxn];
void init()
{
memset(map,inf,sizeof(map));
for(int i=0;i<n;i++)map[i][i]=0;
memset(used,0,sizeof(used));
memset(maxe,0,sizeof(used));
for(int i=0;i<n;i++)pre[i]=i;
}
int prim()
{
int mindis;
int dis[maxn];
int vis[maxn];
int ans=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
pre[i]=1;
dis[i]=map[1][i];
}
pre[1]=0;
dis[1]=0;
vis[1]=1;
for(int i=2;i<=n;i++)
{
mindis=inf;
int k=-1;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&mindis>dis[j])
{
mindis=dis[j];
k=j;
}
}
ans+=mindis;
vis[k]=1;
used[pre[k]][k]=used[k][pre[k]]=1;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&map[j][k]<dis[j])
{
dis[j]=map[j][k];
pre[j]=k;
}
if(vis[j]&&j!=k)maxe[j][k]=maxe[k][j]=max(maxe[pre[k]][j],dis[k]);
//拒绝自环
}
}
return ans;
}
int ans;
int umst()
{
int mindis=inf;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(!used[i][j]&&map[i][j]!=inf)
{
mindis=min(mindis,ans-maxe[i][j]+map[i][j]);
}
}
}
if(mindis==inf)return -1;
return mindis;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int a,b,c;
scanf("%d%d",&n,&m);
init();
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
map[a][b]=map[b][a]=c;
}
ans=prim();
printf("%d %d\n",ans,umst());
}
return 0;
}