您的位置:首页 > 其它

(beginer) 最小生成树 UVA 10600 ACM Contest and Blackout

2014-02-08 09:55 375 查看

Problem A

ACM contest
and Blackout

 

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
题意:找出最小生成树和次小生成树的长度。可能是相等的。
思路:首先找出最小生成树,然后在这个树中求出任意两点之间的最大边权,然后在枚举没有加进最小生成树的边中加边进来,假设加进来的边是(u,v) 那么我们从原来的的生成树中删掉u->v的路径中最大的边。
代码:
#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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: