【克鲁斯卡尔蒜法-最小生成树算法】-zzuli-2271 -Problem -E-魔法交流活动
问题 E: 魔法交流活动
题目描述
魔法学校近日开展了主题为“天气晴朗”的魔法交流活动。
N名魔法师按阵法站好,之后选取N - 1条魔法链将所有魔法师的魔力连接起来,形成一个魔法阵。
魔法链是做法成功与否的关键。每一条魔法链都有一个魔力值V,魔法最终的效果取决于阵中所有魔法链的魔力值的和。
由于逆天改命的魔法过于暴力,所以我们要求阵中的魔法链的魔力值最大值尽可能的小,与此同时,魔力值之和要尽可能的大。
现在给定魔法师人数N,魔法链数目M。求此魔法阵的最大效果。
输入
两个正整数N,M。(1 <= N <= 10^5, N <= M <= 2 * 10^5)
接下来M行,每一行有三个整数A, B, V。(1 <= A, B <= N, INT_MIN <= V <= INT_MAX)
保证输入数据合法。
输出
输出一个正整数R,表示符合条件的魔法阵的魔力值之和。
样例输入
4 6
1 2 3
1 3 1
1 4 7
2 3 4
2 4 5
3 4 6
样例输出
12
-
大致题意分析:
有n个点,选取n-1条边把他们全部连起来形成一棵树,每条边都有一个权值;要求1:所有的边的权值的最大值最小,然后还又要求2:这棵树中的所有的边权值的和最大。
思路:这个题目是对边来进行筛选的,需要用克鲁斯卡尔蒜法。这个蒜法是对边来进行操作的,按照边来逐渐形成整棵最小生成树。
具体需要跑两边,第一遍从小到大对边进行一次筛选,筛选出的边的集合可以构成一颗树即可;这是最后一条新加进来的边就是最大的权值maxmin(要求1达成)。
第二遍,从大到小,具体从等于最小的最大边权值maxlen的边开始跑一遍,直到筛选出的边的集合可以构成一颗树即可,进行筛选、求和,即为最终结果。
ac代码:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include<math.h>
#include <string.h>
#include<set>
using namespace std;
#define inf 0x7fffffff
#define maxn 10000000
const double pi=acos(-1.0);
#define ll long long
#define N 100008 int n,m;
struct Edge//存边的结构体
{
int a,b;//两个顶点的编号
ll dis;
Edge(int a=,int b=,ll dis=):a(a),b(b),dis(dis) {}
} edge[N*]; int root[N]; int findroot(int a) //返回点a的根节点,并查集
{
if(root[a]==a)
return a;
return root[a]=findroot(root[a]);
}
int unite(int a,int b) //将a和b节点用并查集的思路连接到一起
{
if(a==b)return ;//在联通块内部加上的边,及a-b出现在同一个集合内部了
else
{
root[a]=b;
return ;
}
}
bool cmp(Edge x,Edge y)
{
return x.dis<y.dis;
}
int fact1(int n) //kruscal蒜法调用1次,计算出最小的最大值maxlen
{
for(int i=; i<=n; i++)
root[i]=i; int cnt=;
ll ans=(ll)inf*(-);
int i=;
while(cnt<n-)//从小到大
{
if(unite(findroot(edge[i].a),findroot(edge[i].b))== )
{
cnt++;
ans=max(ans,edge[i].dis);
}
i++;
}
return ans;
}
ll fact2(int n,int maxlen) //kruscal蒜法调用2次,求出在manlen范围下的最小生成树的边集的和
{
for(int i=; i<=n; i++)
root[i]=i;
int cnt=;
ll ans=;
int i=m;
while(cnt<n-)//从大到小跑边
{
if(edge[i].dis<=(ll)maxlen && unite(findroot(edge[i].a),findroot(edge[i].b))== )
{
cnt++;//统计不形成回路的边数,等于n-1时跳出循环
ans+=edge[i].dis;
}
i--;
}
return ans;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{ int x,y;
ll v;
for(int i=; i<=m; i++)
{
scanf("%d%d%lld",&x,&y,&v);
edge[i]=Edge(x,y,v);//不习惯这种方式可以手动逐一赋值! }
sort(edge+,edge++m,cmp);//按边权值升序排列 int maxlen=fact1(n);//找到合法的最大长度 printf("%lld\n",fact2(n,maxlen));//求出最终结果
} return ;
}
【克鲁斯卡尔蒜法-最小生成树算法】-zzuli-2271 -Problem -E-魔法交流活动的更多相关文章
- c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树
c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树 最小生成树(Minimum Cost Spanning Tree)的概念: 假设要在n个城市之间建立公路,则连通n个城市只需要n-1条线路 ...
- 最小生成树之克鲁斯卡尔(Kruskal)算法
学习最小生成树算法之前我们先来了解下 下面这些概念: 树(Tree):如果一个无向连通图中不存在回路,则这种图称为树. 生成树 (Spanning Tree):无向连通图G的一个子图如果是一颗包含G的 ...
- 克鲁斯卡尔(Kruskal)算法
概览 相比于普里姆算法(Prim算法),克鲁斯卡尔算法直接以边为目标去构建最小生成树.从按权值由小到大排好序的边集合{E}中逐个寻找权值最小的边来构建最小生成树,只要构建时,不会形成环路即可保证当边集 ...
- JS实现最小生成树之克鲁斯卡尔(Kruskal)算法
克鲁斯卡尔算法打印最小生成树: 构造出所有边的集合 edges,从小到大,依次选出筛选边打印,遇到闭环(形成回路)时跳过. JS代码: //定义邻接矩阵 let Arr2 = [ [0, 10, 65 ...
- 数据结构与算法——克鲁斯卡尔(Kruskal)算法
目录 应用场景-公交站问题 克鲁斯卡尔算法介绍 克鲁斯卡尔算法图解 克鲁斯卡尔算法分析 如何判断回路? 代码实现 无向图构建 克鲁斯卡尔算法实现 获取一个点的终点解释 应用场景-公交站问题 某城市新增 ...
- 克鲁斯卡尔(Kruskal)算法(代码)
算法代码 C#代码 using System; using System.Linq; namespace Kruskal { class Program { static void Main(stri ...
- 最小生成树之Kruskal(克鲁斯卡尔)算法
学习最小生成树算法之前我们先来了解下下面这些概念: 树(Tree):如果一个无向连通图中不存在回路,则这种图称为树. 生成树 (Spanning Tree):无向连通图G的一个子图如果是一颗包含G的所 ...
- 经典问题----最小生成树(kruskal克鲁斯卡尔贪心算法)
题目简述:假如有一个无向连通图,有n个顶点,有许多(带有权值即长度)边,让你用在其中选n-1条边把这n个顶点连起来,不漏掉任何一个点,然后这n-1条边的权值总和最小,就是最小生成树了,注意,不可绕成圈 ...
- [数据结构]最小生成树算法Prim和Kruskal算法
最小生成树 在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树. 例如,对于如上图G4所示的连通网可以有多棵权值总 ...
随机推荐
- Appium移动自动化测试-----(七)Desired Capabilities
Desired Capabilities Desired Capabilities 在启动 session 的时候是必须提供的. Desired Capabilities 本质上是以 key valu ...
- C++大数运算模板
#include<iostream> #include<cstring> #include<cstdio> #include<iomanip> #inc ...
- why use reverse proxy in asp.net core
开篇论点 Asp.net Core自带了Kestrel, 为什么我们还要使用诸如IIS.Apache或者Nginx来做反向代理呢? 原因分析 Kestrel用来承载Asp.net Core的动态内容是 ...
- LeetCode 605. 种花问题(Can Place Flowers) 6
605. 种花问题 605. Can Place Flowers 题目描述 假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去. ...
- 最详细的maven教程
转载 https://blog.csdn.net/wymrdjm/article/details/78695956 所有用Maven管理的真实的项目都应该是分模块的,每个模块都对应着一个pom.x ...
- [WCF] - 访问任意方法耗时长问题之解决
问题 访问 WCF 任意方法耗时都很长(15s+) 原因 当执行语句 log4net.Config.XmlConfigurator.Configure(); 时需要连接到 log4net 对应的数据库 ...
- Python20之全局变量和局部变量
一.局部变量和全局变量 局部变量:是指在函数体内定义的变量,作用域只在该函数体内部 全局变量:是指在函数体外定义的变量,作用域是整个代码段 所以在函数体内可以直接访问全局变量而不可以在函数体外访问局部 ...
- VMware虚拟机(Ubuntu)通过主机代理实现——浏览器+终端访问外网
环境说明:主机win10 + 虚拟机ubunut16.04 + 主机s-h-a-d-o-w-socks win10 主机相关操作配置1: 按下 Win + R 快捷键,输入 cmd ,然后在命令行中输 ...
- Oracle随笔之用拆分后的列数据关联表查询
-----------------------建表------------------------- create table test(id int, plist varchar2(30)) ; c ...
- 百人研发团队的难题:研发管理、绩效考核、组织文化和OKR
分享一个公司规模近200,研发占一半的创业公司 Worktile 在研发团队管理方面的玩法,仅供百人左右研发团队参考~ 什么是研发团队?简单的说,你熟悉的那帮穿格子衬衫,以程序员为核心组成的团队,就是 ...