UVA - 1060次小生成树模板题 ACM Contest and Blackout

ACM Contest and Blackout

另一道模板题题解

#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<vector>
#define ll long long
#define inf 100000008
#define mod 1000000007
using namespace std;

const int maxn=110;  //数组要开够
int n,m,fa[maxn];
struct Edge{
    int u,v,cost;
}t[maxn*maxn];

bool cmp(Edge a,Edge b){
    return a.cost<b.cost;
}

int find(int x){
    return (x==fa[x])?x:fa[x]=find(fa[x]);
}
void merge(int x,int y){
    fa[find(x)]=find(y);
}

void init(){
    for(int i=1;i<=n;i++) fa[i]=i;
}

int ncase;
int main(){
    cin>>ncase;
    while(ncase--){
        cin>>n>>m;
        for(int i=1;i<=m;i++){
            int u,v,cost;
            scanf("%d%d%d",&u,&v,&cost);
            t[i].u=u;t[i].v=v;t[i].cost=cost;
        }
        init();
        sort(t+1,t+m+1,cmp);
        int mct=0;
        vector<Edge> mst;
        for(int i=1;i<=m;i++){
            int u=t[i].u,v=t[i].v;
            if(find(u)!=find(v)){
                mct+=t[i].cost;
                merge(u,v);
                mst.push_back(t[i]);
            }
        }//生成了最小树
        
        int smct=inf;
        for(int i=0;i<mst.size();i++){
            init();
            int cnt=0;
            int sec_mct=0;
            for(int j=1;j<=m;j++){
                if(mst[i].u==t[j].u&&mst[i].v==t[j].v) continue;
                int u=t[j].u,v=t[j].v;
                if(find(u)!=find(v)){  //保证无环
                    sec_mct+=t[j].cost;
                    merge(u,v);
                    cnt++;
                }
                if(cnt==n-1){
                    smct = min(sec_mct,smct);
                    break;
                }
            }
        }
        printf("%d %d\n",mct,smct);
    }
    return 0;
}
发布了67 篇原创文章 · 获赞 0 · 访问量 1516

猜你喜欢

转载自blog.csdn.net/qq_44846324/article/details/104520563