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; }
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。