UVa:10600 ACM Contest and Blackout

来源:互联网 发布:js window 关闭事件 编辑:程序博客网 时间:2024/06/04 19:46

求最小生成树和次小生成树。

次小生成树和最小生成树是不一样的。枚举最小生成树上的一条边并在原来的边集数组中删掉,然后对边集数组求最小生成树。这样得到的所有最小生成树取最小的,就是原图的次小生成树。

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <vector>#include <cmath>#include <queue>#include <algorithm>#define ll long long#define INF 2139062143#define inf -2139062144#define MOD 20071027#define MAXN 105using namespace std;int father[MAXN];int find(int p){    return p==father[p]?p:(father[p]=find(father[p]));}struct Edge{    int a,b,w;    bool operator < (const Edge & p) const    {        return w<p.w;    }};vector<Edge> vec;vector<int> eg;vector<int> ans;int main(){    int T;    scanf("%d",&T);    while(T--)    {        int n,m;        scanf("%d%d",&n,&m);        int a,b,w;        vec.clear();        ans.clear();        eg.clear();        for(int i=0; i<m; ++i)        {            scanf("%d%d%d",&a,&b,&w);            vec.push_back(Edge {a,b,w});        }        sort(vec.begin(),vec.end());        int ans1=0;        for(int i=1; i<=n; ++i) father[i]=i;        for(int i=0; i<vec.size(); ++i)        {            int fa=find(vec[i].a),fb=find(vec[i].b);            if(fa!=fb)            {                ans1+=vec[i].w;                father[fb]=fa;                eg.push_back(i);            }        }        for(int i=0; i<eg.size(); ++i)        {            for(int j=1; j<=n; ++j) father[j]=j;            int res=0,c=0;            for(int j=0; j<vec.size(); ++j)                if(j!=eg[i])                {                    int fa=find(vec[j].a),fb=find(vec[j].b);                    if(fa!=fb)                    {                        res+=vec[j].w;                        father[fb]=fa;                        c++;                    }                }            if(c==n-1) ans.push_back(res);        }        sort(ans.begin(),ans.end());        printf("%d %d\n",ans1,ans[0]);    }    return 0;}


 

0 0
原创粉丝点击