次小生成树模板(坑惨了)

来源:互联网 发布:mac玩游戏时dock栏 编辑:程序博客网 时间:2024/05/29 18:25

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 105using 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;}
原创粉丝点击