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 |
Sample Output |
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 |
110 121 37 37 |
#include<iostream> #include<stdio.h> #include<cstring> #include<string.h> #include<algorithm> #include<vector> using namespace std; const int maxn = 110; const int inf = 1e9; int n , m; int p[maxn]; int maxcost[maxn][maxn]; bool vis[maxn]; bool sel[maxn*maxn]; int find(int x) { if (x==p[x]) return x; return p[x] = find(p[x]); } struct Edge { Edge(int uu=0,int vv=0,int ww=0) : u(uu) , v(vv) , w(ww) { } int u , v , w; }edge[maxn*maxn]; inline bool operator < (const Edge &e1,const Edge &e2) { return e1.w < e2.w; } vector<Edge> G[maxn]; inline int max(int a,int b) { return a < b ? b : a; } void input() { int u ,v , w; for (int i = 0 ; i < m ; ++i) { scanf("%d%d%d",&u,&v,&w); edge[i] = Edge(u,v,w); } sort(edge,edge+m); } void dfs(int s,int x,int maxc) { if (vis[x]) return; vis[x] = true; if (maxcost[s][x] < maxc) maxcost[s][x] = maxc; for (int i = 0 ; i < G[x].size() ; ++i) { int y = G[x][i].v; dfs(s,y,max(maxc,G[x][i].w)); } } void solve() { for (int i = 1 ; i <= n ; ++i) p[i] = i , G[i].clear(); int u , v , w; int S1 = 0 , S2 = inf; for (int i = 0 ; i < m ; ++i) { sel[i] = false; u = find(edge[i].u); v = find(edge[i].v); if (u==v) continue; sel[i] = true; p[u] = v; u = edge[i].u , v = edge[i].v; w = edge[i].w; G[u].push_back(Edge(u,v,w)); G[v].push_back(Edge(v,u,w)); S1 += w; } memset(maxcost,-1,sizeof(maxcost)); printf("%d ",S1); for (int i = 1 ; i <= n ; ++i) { memset(vis,false,sizeof(vis)); dfs(i,i,-1); } for (int i = 0 ; i < m ; ++i) if (!sel[i]) S2 = min(S2,S1+edge[i].w-maxcost[edge[i].u][edge[i].v]); printf("%d\n",S2); } int main() { int T; cin>>T; while (T--) { scanf("%d%d",&n,&m); input(); solve(); } }