upd on 2022.9.3:增加了对解法的描述。
有一张有 \(N\) 个点,编号为 \(1 - N\) 的无向图。
做 \(M\) 次操作,每次操作给出三个正整数 \(L,R,C\),对于每对 \(≥L\) 且 \(≤R\) 的整数对 \((S,T)\) ,在 \((S,T)\) 之间添加一条长度为 \(C\) 的边
完成操作后,找出操作后无向图的最短路。
线段树优化建图裸题。
建议先完成线段树优化建图模板题 CF786B
看到区间向区间连边,显然暴力处理是 \(O(MN)\) 的,会时间超限。
那么可以想到处理区间问题的常用工具:线段树。
我们对整个区间建立线段树,把每个点分为入点和出点,构建出入树和出树。
对于入树,从父节点向子节点连长度为 \(0\) 的边,对于出树,从子节点向父节点连长度为 \(0\) 的边,并且两棵树的对应叶子结点连长度为 \(0\) 的边。
在实现上述过程的时候,我们其实只要建一遍线段树。对于叶子结点,我们可以让两棵树共用,就不必再连边了。
那么对于一个点向一个区间连边,我们可以将其转化为这个点和区间在入树上分成的若干子区间对应的节点连边。
区间向点连边同理,将出树上该区间分成的子区间分别向这个点连边。
题目要求我们区间向区间连边,这个时候我们可以新建一个节点,将出树区间向这个节点连边,这个点再向入树区间连边,就可以了。
然后剩下的就是在建好的图上跑最短路板子,我用的堆优化的 Dijkstra,就不赘述了。
细节可以看代码注释。
#include <bits/stdc++.h>
#define gc() getchar()
using namespace std;
typedef long long ll;
template <typename T> void rd(T &x){
T f=1;x=0;char c=gc();
for(;!isdigit(c);c=gc())if(c=='-')f=-1;
for(;isdigit(c);c=gc())x=(x<<1)+(x<<3)+(c^48);
x*=f;
}
const int MAXN=2e6+5;// 数组大小,开太小会 RE
// 链式前向星存图
int n,m,cnt,hd[MAXN];
struct nd{
int nxt,v,w;
}g[MAXN<<1];
inline void add(int u,int v,int w){
g[++cnt].nxt=hd[u],g[cnt].v=v,g[cnt].w=w,hd[u]=cnt;
}
// 线段树
int tot,in[MAXN],out[MAXN];// tot 从 n 开始,in 存的是入树节点对应的图中节点编号,out 同理
struct sgt{
int l,r;
}t[MAXN];
// 建树
inline void build(int o,int l,int r){
t[o].l=l,t[o].r=r;
if(l==r){
in[o]=out[o]=l;// 如果是叶子节点,那么对应图中节点编号就是其下标,入树出树共用
return;
}
int mid=l+r>>1;
in[o]=++tot,out[o]=++tot;// 存储 o 代表的区间对应的图中节点
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);// 递归建树
add(out[o<<1],out[o],0);
add(out[o<<1|1],out[o],0);// 将出树从子节点向父节点连零边
add(in[o],in[o<<1],0);
add(in[o],in[o<<1|1],0);// 将入树从父节点向子节点连零边
}
// 加边
inline void addedge(int o,int l,int r,int u,int w){
if(t[o].l>=l&&t[o].r<=r){
add(out[o],u,0);// 从出树区间向新建节点连零边
add(u,in[o],w);// 从新建节点向入树区间连长度为 w 的边
return;
}
int mid=t[o].l+t[o].r>>1;
// 递归加边
if(l<=mid)addedge(o<<1,l,r,u,w);
if(r>mid)addedge(o<<1|1,l,r,u,w);
}
// Dijkstra
const ll inf=0x3f3f3f3f3f3f3f3f;
ll d[MAXN];
int vis[MAXN];
// 堆优化
struct pq{
int v;ll w;
pq(){}
pq(int _v,ll _w){v=_v,w=_w;}
bool operator<(const pq &a)const{return w>a.w;}
};
priority_queue<pq>q;
inline void dij(){
memset(d,0x3f,sizeof(d));
d[1]=0;q.push(pq(1,0));
while(!q.empty()){
pq x=q.top();q.pop();
int u=x.v;if(vis[u])continue;
vis[u]=1;
for(int i=hd[u];i;i=g[i].nxt){
int v=g[i].v,w=g[i].w;
if(d[v]>d[u]+w)d[v]=d[u]+w,q.push(pq(v,d[v]));
}
}
}
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
rd(n),rd(m);tot=n;// tot 从 n 开始,避免与叶子节点重复
build(1,1,n);// 别忘了建树
for(int i=1;i<=m;++i){
int l,r,w;
rd(l),rd(r),rd(w);
addedge(1,l,r,++tot,w);// ++tot 新建节点
}
dij();
printf("%lld\n",d[n]==inf?-1:d[n]);// 记得开 long long
return 0;
}
\(by\ sysong\)
\(2022.8.30\)
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我正在尝试使用“updated_at”字段的日期时间范围查询数据库。前端在JSON数组中发送查询:["2015-09-0100:00:00","2015-10-0223:00:00"]在RailsController中,我使用以下方法将两个字符串解析为DateTime:start_date=DateTime.parse(params[:date_range_arr][0])end_date=DateTime.parse(params[:date_range_arr][1])#...@events=@events.where('updated_atBETWEEN?AND?,start_d
Activeadmingem已添加到我的rails项目中,但每次我尝试安装railsgactive_admin:install时,我都会收到类似的错误git://github.com/activeadmin/activeadmin.git(atmaster)isnotyetcheckedout.Runbundleinstallfirst.我肯定在运行“railsgactive_admin:install”之前运行了bundle。运行“bundleshow”后,我看到我已将“*activeadmin(1.0.0.pre3f916d6)”添加到我的项目中,但不断收到此错误消息。我的gem文
我想在服务器启动时在我的Rails应用程序中订阅一个mqtt主题,并保持订阅始终处于事件状态和运行状态。我正在使用这个mqttgem进行mqtt通信:https://github.com/njh/ruby-mqtt这是我现在拥有的:在application.rb中:config.after_initializedomqttSub=BackgroundMQTT.newmqttSub.runend后台MQTT类:classMQTTSubscriberdefrunThread.newdoMQTT::Client.connect(:host=>'localhost',:port=>1883,)
编辑:更改了标题。我对两个部分是否相同不太感兴趣,而是如果它们在一定的公差范围内彼此共线。如果是这样,那么这些线应该聚集在一起作为一个单独的线段。编辑:我想有一个简短的说法:我试图以一种有效的方式将相似的线段聚集在一起。假设我有线段f(fx0,fy0)和(fx1,fy1)和g(gx0,gy0)和(gx1,gy1)这些来自计算机视觉算法边缘检测器之类的东西,在某些情况下,两条线基本相同,但由于像素容差而被视为两条不同的线。有几种情况f和g共享完全相同的端点,例如:f=(0,0),(10,10)g=(0,0),(10,10)f和g共享大致相同的端点和大致相同的长度,例如:f=(0,0.01
我在RubyonRails4.1.4上有一个项目,使用来自git://github.com/activeadmin/activeadmin的activeadmin1.0.0.pre,pg0.17.1,PostgreSQL9.3在项目中我有这些模型:类用户has_one:账户类账户属于:用户有很多:project_accountshas_many:项目,:through=>:project_accounts类项目#该项目有一个bool属性'archive'has_many:project_accounts类ProjectAccount属于:帐户属于:项目我有一个任务是在索引页面上实现一个
我尝试在IRB(v0.9.6,Ruby2.3.0)中使用Refinement:moduleFoorefineObjectdodeffoo()"foo"endendendusingFoo#=>RuntimeError:main.usingispermittedonlyattoplevel这基本上是theexactsetupfromthedocumentation(这会导致相同的错误)。出了什么问题?我该如何解决这个问题? 最佳答案 这可能是IRb的错误或功能不当。众所周知,由于IRb的实现方式非常骇人听闻,因此它无法在所有极端情况下正
当我运行时::$vagrantprovision或:$vagrantup我有一个错误:nisevi@localhostprocessor(master):$vagrantprovisionUsingsshdeploykeyof:/home/nisevi/.ssh/id_rsa==>default:Chef12.0.3Omnibuspackageisalreadyinstalled.==>default:Runningprovisioner:shell...default:Running:inlinescript==>default:W==>default::==>default:Dup
我有一个操作需要在我的Rails应用程序终止之前在我的Rails应用程序中执行。我可以在Rails中为此使用一个钩子(Hook)吗?我猜类似于at_exit的东西。 最佳答案 Ruby本身支持两个钩子(Hook),BEGIN和END,它们在脚本开始时运行,并在解释器停止运行时运行。有关详细信息,请参阅“WhatdoesRuby'sBEGINdo?”。BEGIN文档说:Designates,viacodeblock,codetobeexecutedunconditionallybeforesequentialexecutionofth
如何在不使用sleep(1.second)方法的情况下编写规范?当我取消sleep时,我的测试会因为返回相同的时间戳而中断吗?我有以下类方法:defskipqs=find_or_create_by(user_id:user_id)qs.set_updated_atqs.n_skip+=1qs.save!end和以下规范:qs=skip(user.id)sleep(1.second)qs2=skip(user.id)qs.should_notbe_nilqs2.should_notbe_nil(qs.updated_at 最佳答案 我