ACM Contest and Blackout (次小生成树)
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 <bits/stdc++.h>
using namespace std;
const int maxn = 105;
struct node {
int from,to,date;
int via;
} a[maxn*maxn];
int n,m;
int pre[maxn];
int maxd[maxn][maxn];
vector <int> G[maxn];
bool rule( node a, node b )
{
return a.date<b.date;
}
int root( int x )
{
if ( x!=pre[x] ) {
x = root(pre[x]);
}
return pre[x];
}
void kruskal()
{
int i,j,k;
for ( i=0; i<=n; i++ ) {
pre[i] = i;
G[i].clear();
G[i].push_back(i);
}
sort(a,a+m,rule);
int sum = 0;
int tot = 0;
for ( i=0; i<m; i++ ) {
if ( tot==n-1 ) {
break ;
}
int x = root(a[i].from);
int y = root(a[i].to);
if ( x!=y ) {
a[i].via = 1;
sum += a[i].date;
tot ++;
int len_x = G[x].size();
int len_y = G[y].size();
for ( j=0; j<len_x; j++ ) {
for ( k=0; k<len_y; k++ ) {
maxd[ G[x][j] ][ G[y][k] ] = maxd[ G[y][k] ][ G[x][j] ] = a[i].date;
}
}
pre[x] = y;
for ( j=0; j<len_x; j++ ) {
G[y].push_back(G[x][j]);
}
}
}
cout << sum << " ";
int cisum = 0x3f3f3f3f;
for ( i=0; i<m; i++ ) {
if ( a[i].via==0 ) {
cisum = min( cisum, sum+a[i].date-maxd[a[i].from][a[i].to] );
}
}
cout << cisum << endl;
}
int main()
{
int listt,i,j;
cin >> listt;
while ( listt-- ) {
cin >> n >> m;
for ( i=0; i<m; i++ ) {
cin >> a[i].from >> a[i].to >> a[i].date;
a[i].via = 0;
}
kruskal();
}
return 0;
}