ACM Contest and Blackout UVA

来源:互联网 发布:linux 办公软件 编辑:程序博客网 时间:2024/05/17 18:14

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.

次小生成树模版 O(mlogm + n^2)

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <cmath>#include <vector>using namespace std;const int MaxN = 100;struct node{    int u, v, w;    node(int v, int w):v(v), w(w){}    node(){}    bool operator < (const node &x) const    {        return w < x.w;    }}e[MaxN * MaxN + 1];int n, m;vector<node> g[MaxN + 1];int f[MaxN + 1];bool vis[MaxN + 1];int path[MaxN + 1][MaxN + 1];int find(int x){    if (x != f[x])        f[x] = find(f[x]);    return f[x];}void dfs(int step, int x, int d){    vis[step] = true;    path[step][x] = path[x][step] = d;    for (int i = 0; i < g[step].size(); i++)    {        int v = g[step][i].v;        if (!vis[v])        {            vis[v] = true;            dfs(v, x, max(d, g[step][i].w));        }    }}int main(){    int T;    scanf("%d", &T);    while (T--)    {        scanf("%d %d", &n, &m);        for (int i = 1; i <= m; i++)            scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].w);        sort(e + 1, e + m + 1);        for (int i = 1; i <= n; i++)            f[i] = i;        int sum = 0;        bool mark[MaxN * MaxN + 1] = {0};        for (int i = 1; i <= n; i++)            g[i].clear();        for (int i = 1; i <= m; i++)        {            int x = find(e[i].u), y = find(e[i].v);            if (x != y)            {                g[e[i].u].push_back(node(e[i].v, e[i].w));                g[e[i].v].push_back(node(e[i].u, e[i].w));                f[y] = x;                mark[i] = true;                sum += e[i].w;            }        }        memset(path, -1, sizeof(path));        for (int i = 1; i <= n; i++)        {            memset(vis, 0, sizeof(vis));            dfs(i, i, -1);        }        int ans = 0x3f3f3f3f;        for (int i = 1; i <= m; i++)            if (!mark[i])                ans = min(ans, sum - path[e[i].u][e[i].v] + e[i].w);        printf("%d %d\n", sum, ans);    }    return 0;}
原创粉丝点击