51nod 1640 天气晴朗的魔法 二分 + 克鲁斯卡算法(kruskal算法) 做复杂了
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1640
一开始想的时候,看到要使得最大值最小,那这样肯定是二分这个最大值了,然后每一次都跑一次kruskal
这样的复杂度是O(E * 64),然后被卡TLE了
然后观察到kruskal的时候,如果最大边是val,那么比val大的是不要的了,然后整个数组也是有序的。
比如7、6、5、4、3、2、1等,这个也是可以lower_bound的,然后lower_bound后就能过,600ms
改了lower_bound后,我忘记删除那个if了,居然还是超时。TAT,这数据有点强。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
int n, m;
const int maxn = 2e5 + ;
struct Edge {
int u, v, w;
bool operator < (const struct Edge & rhs) const {
return w > rhs.w;
}
}e[maxn];
int fa[maxn];
void init() {
for (int i = ; i <= n; ++i) fa[i] = i;
}
int tofind(int u) {
if (fa[u] == u) return u;
else return fa[u] = tofind(fa[u]);
}
void tomerge(int x, int y) {
x = tofind(x);
y = tofind(y);
fa[y] = x;
}
LL nowAns;
bool check(LL val) {
init();
int sel = ;
nowAns = ;
struct Edge t;
t.w = val;
int pos = lower_bound(e + , e + + m, t) - e;
for (int i = pos; i <= m; ++i) {
// if (e[i].w > val) continue; 卡TLE
if (tofind(e[i].u) == tofind(e[i].v)) continue;
tomerge(e[i].u, e[i].v);
nowAns += e[i].w;
sel++;
if (sel == n - ) {
return true;
}
}
return false;
}
void work() {
scanf("%d%d", &n, &m);
LL lo = 1e18L, hi = -1e18L;
for (int i = ; i <= m; ++i) {
scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
lo = min(lo, (LL)e[i].w);
hi = max(hi, (LL)e[i].w);
}
sort(e + , e + + m);
while (lo <= hi) {
LL mid = (lo + hi) >> ;
if (check(mid)) {
hi = mid - ;
} else lo = mid + ;
}
check(lo);
// printf("%lld\n", nowAns);
cout << nowAns << endl;
// struct Edge t;
// t.w = 3;
// int pos = lower_bound(e + 1, e + 1 + m, t) - e;
// cout << pos << endl;
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}
然后就上网看题解了,然后发现自己做法很复杂了。
感觉是题意弄得我们想复杂了,又魔法连的值,又总和,
正解是kruskal两次,第一次就能找出最大值最小,然后从大的再kruskal一次。
但是为什么还是700ms,有点坑。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
int n, m;
const int maxn = 2e5 + ;
struct Node {
int u, v, w;
bool operator < (const struct Node & rhs) const {
return w < rhs.w;
}
}e[maxn];
bool cmp(struct Node a, struct Node b) {
return a.w > b.w;
}
int fa[maxn];
int tofind(int u) {
if (fa[u] == u) return u;
else return fa[u] = tofind(fa[u]);
}
void tomerge(int x, int y) {
x = tofind(x);
y = tofind(y);
fa[y] = x;
}
void init() {
for (int i = ; i <= n; ++i) fa[i] = i;
}
int result() {
init();
int sel = ;
for (int i = ; i <= m; ++i) {
if (tofind(e[i].u) == tofind(e[i].v)) continue;
tomerge(e[i].u, e[i].v);
sel++;
if (sel == n - ) return e[i].w;
}
}
void work() {
scanf("%d%d", &n, &m);
for (int i = ; i <= m; ++i) {
scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
}
sort(e + , e + + m);
int mx = result();
sort(e + , e + + m, cmp);
init();
LL ans = ;
int sel = ;
for (int i = ; i <= m; ++i) {
if (e[i].w > mx) continue;
if (tofind(e[i].u) == tofind(e[i].v)) continue;
tomerge(e[i].u, e[i].v);
sel++;
ans += e[i].w;
if (sel == n - ) break;
}
printf("%lld\n", ans);
// cout << ans << endl;
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}
51nod 1640 天气晴朗的魔法 二分 + 克鲁斯卡算法(kruskal算法) 做复杂了的更多相关文章
- 51Nod - 1640 天气晴朗的魔法 大+小生成树(最大值最小)/二分
天气晴朗的魔法 这样阴沉的天气持续下去,我们不免担心起他的健康. 51nod魔法学校近日开展了主题为“天气晴朗”的魔法交流活动. N名魔法师按阵法站好,之后选取N - 1条魔法链将所有魔法师的 ...
- 51nod 1640 天气晴朗的魔法
题目来源: 原创 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 这样阴沉的天气持续下去,我们不免担心起他的健康. 51nod魔法学校近日开展了主题为“天气晴朗 ...
- 51nod 1640 天气晴朗的魔法 最小生成树
题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1640 题解: 先求最小生成树,记录最大边. 然后求最大生成树 ...
- 51nod——1640 天气晴朗的魔法 有边权限制的最大生成树
好好读题嗷:“所以我们要求阵中的魔法链的魔力值最大值尽可能的小,与此同时,魔力值之和要尽可能的大.” 第一条件是生成树的最大边权更小,第二条件是在最大边权的限制下搞一个最大生成树. 至于最大生成树,如 ...
- 51 Nod 1640 天气晴朗的魔法( Kruskall )
#include <bits/stdc++.h> typedef long long LL; using namespace std; ; struct node{ LL u,v,w; n ...
- 51nod 天气晴朗的魔法 - (Kruskall最小生成树)
题目: 基准时间限制:1 秒 空间限制:131072 KB 51nod魔法学校近日开展了主题为“天气晴朗”的魔法交流活动. N名魔法师按阵法站好,之后选取N - 1条魔法链将所有魔法师的魔力连接 ...
- 51nod 1640 MST+二分
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1640 1640 天气晴朗的魔法 题目来源: 原创 基准时间限制:1 秒 ...
- 51nod-1640--天气晴朗的魔法(简单最小生成树)
1640 天气晴朗的魔法 题目来源: 原创 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 这样阴沉的天气持续下去,我们不免担心起他的健康. 51nod魔法学校近日 ...
- javascript数据结构与算法---检索算法(二分查找法、计算重复次数)
javascript数据结构与算法---检索算法(二分查找法.计算重复次数) /*只需要查找元素是否存在数组,可以先将数组排序,再使用二分查找法*/ function qSort(arr){ if ( ...
随机推荐
- hdu 2671 shǎ崽 OrOrOrOrz(排序)
题意:排序后按题目要求输出 思路:排序 #include<iostream> #include<stdio.h> #include<algorithm> using ...
- .Net-Mongodb学习大全网址
http://www.yuanjiaocheng.net/csharpmongo/16.html 介绍 在上一篇文章中,我们继续探索MongoDb .NET驱动程序中的数据序列化. 我们查看了各种属性 ...
- python中通过xlwt、xlrd和xlutils操作xls
xlwt模块用于在内存中生成一个xls/xlsx对象,增加表格数据,并把内存中的xls对象保存为本地磁盘xls文件; xlrd模块用于把本地xls文件加载到内存中,可以读取xls文件的表格数据,查询x ...
- bootstrap 学习笔记(1)---介绍bootstrap和栅格系统
学习前端许久,对于布置框架和响应浏览器用html 和javascript 写的有点繁琐,无意间看到这个框架,觉得挺好用的就开始学习了,但是这个框架上面有很多知识,不是所有的都要学的,故将学习笔记和觉得 ...
- Win32编程点滴5 - 响应ActiveX控件的事件
在最近的一篇文章中说到了,如何创建ActiveX,这次我们来响应事件.这次,我们将创建一个类:CGeneralEventSink,它能够响应任何Dispatch事件(事件的接口继承与IDispatch ...
- JS-React:React.js
ylbtech-JS-React:React.js react (软件行业名词) React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意 ...
- Code-NFine:.NET快速开发平台 NFine.Framework Web框架
ylbtech-Code-NFine:.NET快速开发平台 NFine.Framework Web框架 1.NFine.Framework 详细介绍返回顶部 1. NFine 是基于 C# 语言的极速 ...
- 在调试javascript的时候,要常使用alert()
在调试javascript的时候,要常使用alert()会帮助我们定位脚本错误.
- Flutter实战视频-移动电商-39.路由_Fluro的路由配置和静态化
39.路由_Fluro的路由配置和静态化 handler只是单个路由的配置,这节课我们要学习路由的整体配置 整体配置 新建routers.dart文件来做整体配置 detailsHandler就是我们 ...
- 洛谷 - P2158 - 仪仗队 - 欧拉函数
https://www.luogu.org/problemnew/show/P2158 好像以前有个妹子收割铲也是欧拉函数. 因为格点直线上的点,dx与dy的gcd相同,画个图就觉得是欧拉函数.但是要 ...