【JZOJ5060】【GDOI2017第二轮模拟day1】公路建设 线段树+最小生成树
题面
在Byteland一共有n 个城市,编号依次为1 到n,它们之间计划修建m条双向道路,其中修建第i 条道路的费用为ci。
Byteasar作为Byteland 公路建设项目的总工程师,他决定选定一个区间[l, r],仅使用编号在该区间内的道路。他希望选择一些道路去修建,使得连通块的个数尽量少,同时,他不喜欢修建多余的道路,因此每个连通块都可以看成一棵树的结构。
为了选出最佳的区间,Byteasar 会不断选择q 个区间,请写一个程序,帮助Byteasar 计算每个区间内修建公路的最小总费用。

30~60
30分暴力;
60分,考虑到由于边的权值随编号递增,所以对于一个询问区间\([l,r]\),显然能往前取,尽量往前取。
所以,我们把边从大到小加入,对树的结构每次加边后暴力重构,方便加边时LCA。
然后对于一个区间\([l,r]\),就要把\([l,m]\)的边,然后我用数据结构找生成树中编号小于\(r\)的权值和。
100
开棵线段树,树上每个结点表示,使用区间内的边生成的mst,最多存储\(O(n)\)条边,空间就有\(O(n*m*log_m)\)
然后我对于每个询问就只需\(O(log_m*n)\)的时间。
总的时间复杂度为\(O(log_m*n*q)\)。
为什么可以用线段树
前提条件:离线;
关键条件:区间合并只需\(O(n)\)。
Code
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
#define fo(i,x,y) for(int i=x;i<=y;i++)
#define fd(i,x,y) for(int i=x;i>=y;i--)
using namespace std;
const char* fin="highway.in";
const char* fout="highway.out";
const int maxn=107,maxm=100007,maxt=maxm*4;
int n,m,q,t[maxn*2];
struct line{
int x,y,z;
}a[maxm];
struct node{
node(){r[0]=0;}
int r[maxn];
}c[maxt],ans,tmp;
struct bitch{
int data[maxm],az[maxm],id;
bitch(){memset(az,0,sizeof az);id=0;}
void init(){id++;}
int& operator [](const int &v){
if (az[v]<id) az[v]=id,data[v]=0;
return data[v];
}
}dad;
int getdad(int v){return dad[v]==0?v:dad[v]=getdad(dad[v]);}
void merge(node &v,const node &b,const node &c){
t[0]=0;
int i=1,j=1;
while (i<=b.r[0] && j<=c.r[0])
if (a[b.r[i]].z<a[c.r[j]].z) t[++t[0]]=b.r[i++];
else t[++t[0]]=c.r[j++];
while (i<=b.r[0]) t[++t[0]]=b.r[i++];
while (j<=c.r[0]) t[++t[0]]=c.r[j++];
v.r[0]=0;
dad.init();
fo(i,1,t[0]){
int j=getdad(a[t[i]].x),k=getdad(a[t[i]].y);
if (j!=k){
dad[j]=k;
v.r[++v.r[0]]=t[i];
}
}
}
void plant(int l,int r,int t){
int mid=(l+r)/2;
if (l==r){
c[t].r[0]=1;
c[t].r[1]=l;
return;
}
plant(l,mid,t*2);
plant(mid+1,r,t*2+1);
merge(c[t],c[t*2],c[t*2+1]);
}
node query(int l,int r,int t,int v1,int v2){
int mid=(l+r)/2;
if (l>v2 || r<v1) return node();
if (l>=v1 && r<=v2) return c[t];
merge(tmp,query(l,mid,t*2,v1,v2),query(mid+1,r,t*2+1,v1,v2));
return tmp;
}
int main(){
freopen(fin,"r",stdin);
freopen(fout,"w",stdout);
scanf("%d%d%d",&n,&m,&q);
fo(i,1,m){
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
}
plant(1,m,1);
fo(i,1,q){
int l,r;
scanf("%d%d",&l,&r);
ans=query(1,m,1,l,r);
int Ans=0;
fo(j,1,ans.r[0]) Ans+=a[ans.r[j]].z;
printf("%d\n",Ans);
}
return 0;
}
【JZOJ5060】【GDOI2017第二轮模拟day1】公路建设 线段树+最小生成树的更多相关文章
- GDOI2017第二轮模拟day1 总结
平民比赛 这场比赛的暴力分非常友好. 但是我并没有拿到全部的暴力分. 1(暴力分\(60/100\)) 暂时我可以拿的暴力分为\(30/100\),直接mst模拟即可. 然而当时打了个辣鸡莫队,结果爆 ...
- 【JZOJ5064】【GDOI2017第二轮模拟day2】友好城市 Kosarajo算法+bitset+ST表+分块
题面 在Byteland 一共有n 座城市,编号依次为1 到n,这些城市之间通过m 条单向公路连接. 对于两座不同的城市a 和b,如果a 能通过这些单向道路直接或间接到达b,且b 也能如此到达a,那么 ...
- bzoj 5216 [Lydsy2017省队十连测]公路建设 线段树维护 最小生成树
[Lydsy2017省队十连测]公路建设 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 93 Solved: 53[Submit][Status][ ...
- [jzoj5073 GDOI2017第二轮模拟] 影魔
Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵 ...
- BZOJ 1920 Luogu P4217 [CTSC2010]产品销售 (模拟费用流、线段树)
题目链接 (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=1920 (luogu) https://www.luogu.org/prob ...
- BZOJ 5326 [JSOI2017]博弈 (模拟费用流、线段树)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=5326 题解 终于成为第8个A掉这题的人--orz tzw神仙早我6小时 本以为这东西常数 ...
- Codeforces 280D k-Maximum Subsequence Sum [模拟费用流,线段树]
洛谷 Codeforces bzoj1,bzoj2 这可真是一道n倍经验题呢-- 思路 我首先想到了DP,然后矩阵,然后线段树,然后T飞-- 搜了题解之后发现是模拟费用流. 直接维护选k个子段时的最优 ...
- 【10.6校内测试】【小模拟】【hash+线段树维护覆盖序列】
一开始看到题就果断跳到T2了!!没想到T2才是个大坑,浪费了两个小时QAQ!! 就是一道小模拟,它怎么说就怎么走就好了! 为什么要用这么多感叹号!!因为统计答案要边走边统计!!如果每个数据都扫一遍20 ...
- Contest Hunter 模拟赛09 A [线段树维护斜率]
题面 传送门 思路 首先看看我们到底要干什么:有$1e6$次询问,遍历$i$,每次要求一个形如$b_i \ast a_j - a_i \ast b_j$的东西的最大值 考虑如果一个$j$的决策在当前的 ...
随机推荐
- <每日一题>题目20:简单python练习题(11-20)
#11.编写程序,输入一个自然数,输出它的二进制.八进制.十六进制表示形式 Num = input("请输入任性自然数:") Num = eval(Num) print(" ...
- Leetcode515. Find Largest Value in Each Tree Row在每个树行中找最大值
您需要在二叉树的每一行中找到最大的值. 示例: 输入: 1 / \ 3 2 / \ \ 5 3 9 输出: [1, 3, 9] class Solution { public: vector<i ...
- 浪潮云+/云加 App 智能化的企业移动办公平台官网下载地址
上Google?Facebook? 点这里: 手机端:https://ecm.inspur.com/ 桌面端:https://ecm.inspuronline.com/
- Odoo加载机制指导流程
Odoo的启动通过openerp-server脚本完成,它是系统的入口. 然后加载配置文件openerp-server.conf 或者 openerp_serverrc: openerp-server ...
- C语言作用域、链接属性和存储类型
C/C++中作用域详解 作用域 编译器可以确认的4种作用域-代码块作用域.文件作用域.函数作用域和原型作用域,一般来说,标识符(包括变量名和函数名)声明的位置决定它的作用域. (1)代码块作用域 一对 ...
- 让pandoc输出pdf时支持中文
主机环境为:Ubuntu 12.04 LTS.对于RH系列,yum安装包的名称可能会有不同,不过yum联想能力比较强,应该不是问题. 安装pandoc,安装tex-live sudo apt-get ...
- js获取url链接中的域名部分
用js提取出url中的域名(domain)部分,用split()函数就可以了. 因为一个正确的url必定是由http://或者是https://.domain.路径/参数组成,所以可以用split以/ ...
- Error-SQLServer:【失败】win7装SQL server2017
ylbtech-Error-SQLServer:[失败]win7装SQL server2017 1.返回顶部 1. 2018年08月15日 22:06:38 USCWIFI 阅读数:5433 版 ...
- 群晖的moments套件 发生未知错误
一次了,哎 也不知道什么原因引起的 只能再搞一遍 先把homes文件夹数据弄走,免得弄丢 然后卸载momemts,删除数据库 还有其他人遇到这个情况http://www.gebi1.com/threa ...
- tortoisegit如何删除远程分支
图片来自:https://zhidao.baidu.com/question/134542616148384045.html