51nod 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 6
1 2 3
1 3 1
1 4 7
2 3 4
2 4 5
3 4 6
Output示例
12
 
 
二分+kruskal
#include <algorithm>
#include <cstring>
#include <cctype>
#include <cstdio>
#define N 100005
typedef long long LL;
inline void Read(LL &x)
{
    bool f=0;register char ch=getchar();
    for(x=0;!isdigit(ch);ch=getchar()) if(ch=='-') f=1;
    for(;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    x=f?-x:x;
}
using namespace std;
struct node
{
    LL x,y,z;
    bool operator<(node a)const
    {
        return z<a.z;
    }
}edge[N<<1];
LL fa[N],n,m;
LL ans=-0x7fffffff,l,r;
LL find_(LL x) {return fa[x]==x?x:fa[x]=find_(fa[x]);}
LL max(LL a,LL b) {return a>b?a:b;}
LL min(LL a,LL b) {return a>b?b:a;}
bool check(LL x)
{
    for(LL i=1;i<=n;++i) fa[i]=i;
    LL now=0,num=0;
    for(LL i=m;i>=1;--i)
    {
        int fx=find_(edge[i].x),fy=find_(edge[i].y);
        if(fx!=fy&&edge[i].z<=x)
        {
            fa[fy]=fx;
            now+=edge[i].z;
            num++;
            if(num==n-1) break;
        }
    }
    if(num==n-1) {ans=now;return true;} 
    return false;
}
int main()
{
    Read(n);Read(m);
    for(int i=1;i<=m;++i) Read(edge[i].x),Read(edge[i].y),Read(edge[i].z);
    l=-0x7fffffff,r=0x7fffffff;
    sort(edge+1,edge+1+m);
    for(LL mid;l<=r;)
    {
        mid=(l+r)>>1;
        if(check(mid)) r=mid-1;
        else l=mid+1;
    }
    printf("%lld\n",ans);
    return 0;
}

 

posted @ 2017-09-23 19:27  杀猪状元  阅读(230)  评论(0编辑  收藏  举报