首页 > 代码库 > 51nod 1640 天气晴朗的魔法 (最小生成树)

51nod 1640 天气晴朗的魔法 (最小生成树)

 

1640 天气晴朗的魔法技术分享
题目来源: 原创
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
技术分享 收藏
技术分享 关注
技术分享 取消关注
这样阴沉的天气持续下去,我们不免担心起他的健康。
 
51nod魔法学校近日开展了主题为“天气晴朗”的魔法交流活动。
 
N名魔法师按阵法站好,之后选取N - 1条魔法链将所有魔法师的魔力连接起来,形成一个魔法阵。
 
魔法链是做法成功与否的关键。每一条魔法链都有一个魔力值V,魔法最终的效果取决于阵中所有魔法链的魔力值的和。
 
由于逆天改命的魔法过于暴力,所以我们要求阵中的魔法链的魔力值最大值尽可能的小,与此同时,魔力值之和要尽可能的大。
 
现在给定魔法师人数N,魔法链数目M。求此魔法阵的最大效果。
Input
两个正整数N,M。(1 <= N <= 10^5, N <= M <= 2 * 10^5)接下来M行,每一行有三个整数A, B, V。(1 <= A, B <= N, INT_MIN <= V <= INT_MAX)保证输入数据合法。
Output
输出一个正整数R,表示符合条件的魔法阵的魔力值之和。
Input示例
4 61 2 31 3 11 4 72 3 42 4 53 4 6
Output示例
12


分析:要求阵中的魔法链的魔力值最大值尽可能的小,那么最小会小到什么程度呢?最小也不会比用最小生成树算法求得的树中的最大权值小。
所以,这个题用最小生成树算法求出最大权值后,再求有限制的最大生成树即可。

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxe=200005;
const int maxv=100005;
int V,E;
struct edge
{
    int u,v,cost;
};
edge es[maxe];
int par[maxv];
void init(int n)
{
    for(int i=1;i<=n;i++)
    {
        par[i]=i;
    }
}
int find(int x)
{
    if(par[x]==x) return x;
    else return par[x]=find(par[x]);
}
bool same(int x,int y)
{
    return find(x)==find(y);
}
void unit(int x,int y)
{
    int fx=find(x);
    int fy=find(y);
    if(fx==fy) return ;
    else
    {
        par[fx]=fy;
    }
}
bool cmp1(const edge& e1,const edge& e2)
{
    return e1.cost<e2.cost;
}
bool cmp2(const edge& e1,const edge& e2)
{
    return e1.cost>e2.cost;
}
int kur_maxv()
{
    init(V);
    sort(es,es+E,cmp2);
    int ans=-1;
    for(int i=E-1;i>=0;i--)
    {
        if(!same(es[i].u,es[i].v))
        {
            unit(es[i].u,es[i].v);
            int tmp=es[i].cost;
            if(tmp>ans || ans==-1)
                ans=tmp;
        }
    }
    return ans;
}
int main()
{
    scanf("%d%d",&V,&E);
    ll ans=0;
    for(int i=0;i<E;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        es[i].u=x;
        es[i].v=y;
        es[i].cost=z;
    }
        int maxcost=kur_maxv();
        init(V);
        for(int i=0;i<E;i++)
        {
            if(!same(es[i].u,es[i].v) && es[i].cost<=maxcost)
            {
                unit(es[i].u,es[i].v);
                ans+=es[i].cost;
            }
        }

    printf("%lld\n",ans);
    return 0;
}

 

51nod 1640 天气晴朗的魔法 (最小生成树)