解题:AHOI 2005 航线规划
这种不断删边的首先肯定想到时光倒流啊=。=
在最后剩下的连通图上跑出一棵搜索树,先将边权都赋为$1$,那么两点间的关键航线就是链上边权和,而每加入一条非树边$u,v$都会使得$u,v$链上的边的边权变为零。写个树剖,先把非树边加进去,然后逆着做一下就行了。
#include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,M=,Q=;
struct a
{
int n1,n2,t;
int mn(){return min(n1,n2);}
int mx(){return max(n1,n2);}
}edg[M],qry[Q];
bool operator < (a x,a y)
{
return x.mn()==y.mn()?x.mx()<y.mx():x.mn()<y.mn();
}
map<a,bool> mp;
int n,m,typ,tot,num,cnt;
int p[N],noww[*M],goal[*M];
int vis[N],outp[Q],val[*N],laz[*N];
int dfn[N],siz[N],anc[N],dep[N],imp[N],top[N];
void link(int f,int t)
{
noww[++cnt]=p[f];
goal[cnt]=t,p[f]=cnt;
}
void DFS(int nde,int fth,int dth)
{
int tmp=;
siz[nde]=,vis[nde]=true;
anc[nde]=fth,dep[nde]=dth;
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth&&!vis[goal[i]])
{
mp[(a){nde,goal[i],}]=true;
DFS(goal[i],nde,dth+);
siz[nde]+=siz[goal[i]];
if(siz[goal[i]]>tmp)
tmp=siz[goal[i]],imp[nde]=goal[i];
}
}
void mark(int nde,int tpp)
{
top[nde]=tpp,dfn[nde]=++num;
if(imp[nde])
{
mark(imp[nde],tpp);
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=imp[nde]&&goal[i]!=anc[nde])
mark(goal[i],goal[i]);
}
}
void create(int nde,int l,int r)
{
if(l==r)
val[nde]=,laz[nde]=-;
else
{
int mid=(l+r)/,ls=*nde,rs=*nde+;
create(ls,l,mid),create(rs,mid+,r);
val[nde]=val[ls]+val[rs],laz[nde]=-;
}
}
void release(int nde,int l,int r)
{
if(~laz[nde])
{
int mid=(l+r)/,ls=*nde,rs=*nde+;
laz[ls]=laz[nde],laz[rs]=laz[nde];
val[ls]=(mid-l+)*laz[nde];
val[rs]=(r-mid)*laz[nde];
laz[nde]=-;
}
}
void change(int nde,int l,int r,int nl,int nr,int task)
{
if(l>nr||r<nl)
return ;
else if(l>=nl&&r<=nr)
val[nde]=task*(r-l+),laz[nde]=task;
else
{
int mid=(l+r)/,ls=*nde,rs=*nde+; release(nde,l,r);
change(ls,l,mid,nl,nr,task),change(rs,mid+,r,nl,nr,task);
val[nde]=val[ls]+val[rs];
}
}
int query(int nde,int l,int r,int nl,int nr)
{
if(l>nr||r<nl)
return ;
else if(l>=nl&&r<=nr)
return val[nde];
else
{
int mid=(l+r)/,ls=*nde,rs=*nde+; release(nde,l,r);
return query(ls,l,mid,nl,nr)+query(rs,mid+,r,nl,nr);
}
}
int LCA(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y); x=anc[top[x]];
}
return dep[x]<dep[y]?x:y;
}
void path_change(int x,int y)
{
int lca=LCA(x,y),mem=query(,,n,dfn[lca],dfn[lca]);
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
change(,,n,dfn[top[x]],dfn[x],); x=anc[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
change(,,n,dfn[x],dfn[y],),change(,,n,dfn[lca],dfn[lca],mem);
}
int path_query(int x,int y)
{
int ret=;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ret+=query(,,n,dfn[top[x]],dfn[x]); x=anc[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
int lca=LCA(x,y),dec=query(,,n,dfn[lca],dfn[lca]);
return ret+query(,,n,dfn[x],dfn[y])-dec;
}
int main ()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%d%d",&edg[i].n1,&edg[i].n2);
mp[edg[i]]=true;
}
while(scanf("%d",&typ)&&~typ)
{
qry[++tot].t=typ;
scanf("%d%d",&qry[tot].n1,&qry[tot].n2);
if(!typ) mp[qry[tot]]=false;
}
for(int i=;i<=m;i++)
if(mp[edg[i]])
{
link(edg[i].n1,edg[i].n2);
link(edg[i].n2,edg[i].n1);
}
mp.clear(); DFS(,,);
memset(p,,sizeof p),cnt=;
for(int i=;i<=m;i++)
if(mp[edg[i]])
{
link(edg[i].n1,edg[i].n2);
link(edg[i].n2,edg[i].n1);
}
mark(,); create(,,n);
for(int i=;i<=tot;i++)
if(!qry[i].t) mp[qry[i]]=true;
for(int i=;i<=m;i++)
if(!mp[edg[i]]) path_change(edg[i].n1,edg[i].n2);
for(int i=tot;i;i--)
{
if(qry[i].t) outp[++outp[]]=path_query(qry[i].n1,qry[i].n2);
else path_change(qry[i].n1,qry[i].n2);
}
while(outp[]) printf("%d\n",outp[outp[]--]);
return ;
}
解题:AHOI 2005 航线规划的更多相关文章
- [AHOI 2005] 航线规划
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1969 [算法] 首先离线 , 将删边操作转化为加边操作 不妨首先将这张图按边-双连通 ...
- 洛谷 P2542 [AHOI2005]航线规划 解题报告
P2542 [AHOI2005]航线规划 题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系--一个巨大的由千百万星球构成的Samuel星系 ...
- BZOJ 1969: [Ahoi2005]LANE 航线规划( 树链剖分 )
首先我们要时光倒流, 倒着做, 变成加边操作维护关键边. 先随意搞出一颗树, 树上每条边都是关键边(因为是树, 去掉就不连通了)....然后加边(u, v)时, 路径(u, v)上的所有边都变成非关键 ...
- 【BZOJ1969】航线规划(Link-Cut Tree)
[BZOJ1969]航线规划(Link-Cut Tree) 题面 BZOJ 题解 删边操作 套路呀 离线读入倒过来做 变成加边操作 现在考虑怎么确定两点直接的关键路径条数 如果是一棵树,那么每条边都是 ...
- 让大疆去做测绘---航线规划软件APP
让大疆去做测绘---航线规划软件APP http://blog.zhulong.com/u10783270/blogdetail7162540.html RockyCapture无人机航线飞行控制软件 ...
- 【BZOJ 1969】 1969: [Ahoi2005]LANE 航线规划 (树链剖分+线段树)
1969: [Ahoi2005]LANE 航线规划 Description 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星 ...
- 【BZOJ1969】[Ahoi2005]LANE 航线规划 离线+树链剖分+线段树
[BZOJ1969][Ahoi2005]LANE 航线规划 Description 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由 ...
- P2542 【[AHOI2005]航线规划】
P2542 [[AHOI2005]航线规划] 一个无向图,m个操作 删去一条边 给定两个点,求有多少边使得如果这条边不存在,给定的两个点不连通 一般这种删边的题目,考虑逆序加边处理 在删完的图中,任意 ...
- [Ahoi2005]LANE 航线规划
题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星球构成的Samuel星系. 星际空间站的Samuel II巨型计算 ...
随机推荐
- Linux 安装ActiveMQ(使用Mac远程访问)
阅读本文需要安装JDK 一 ActiveMQ简介 activemq是用java语言编写的一款开源消息总线 activemq是apache出品 activemq消息的传递有两种类型 一种是点对点: 即一 ...
- 生成dataset的几种方式
1.常用的方式通过sparksession读取外部文件或者数据生成dataset(这里就不讲了) 注: 生成Row对象的方法提一下:RowFactory.create(x,y,z),取Row中的数据 ...
- Echarts-K线图提示框改头换面
工作: 使用Hbuilder建web工程,加入echarts相关库,根据需要更改K线图及其的提示样式,去除默认提示,使用异步加载echarts的数据,数据格式为json. 需要注意的K线图和5日均线, ...
- js-jQuery对象与dom对象相互转换(转载)
核心提示:jquery选择器得到的jquery对象和标准的 javascript中的document.getElementById()取得的dom对象是两种不同的对象类型,一般情况下,如S(’#id’ ...
- [redis] linux下哨兵篇(3)
一.前言1.为何部署sentinel哨兵前文redis主从架构中,当主服务故障时,需要手动将从服务切换为主服务,sentinel服务就是将这个过程自动化.主要功能有:1)不时监控主从服务正常运行2)可 ...
- activemq 持久化
转自: http://blog.csdn.net/kobejayandy/article/details/50736479 消息持久性的原理很简单,就是在发送者将消息发送出去后,消息中心首先将消息存储 ...
- eFPGA与FPGA SoC,谁将引领下一代可编程硬件之潮流?|半导体行业观察
eFPGA:冉冉升起的新星 eFPGA即嵌入式FPGA(embedded FPGA),是近期兴起的新型电路IP. 随着摩尔定律越来越接近瓶颈,制造ASIC芯片的成本越来越高.因此,设计者会希望ASIC ...
- 在PHP中,是以分好结束一条语句的吗
在PHP中,是以分号结束一条语句的,这个和C语言类似. 但是,有一条例外,对于PHP结束tag之前的语句,是可以不写分号的: <?php if ($a == $b) { echo "R ...
- 寒假MOOC学习计划
我选择的是西北工业大学的课程,理由如下: 首先,选择这门课的网友还蛮多的,特意看了一下评价,也不错: 其次,这个课程的排版与我从图书馆借来的一本书内容排版比较符合,可以结合起来一起看,说不定会有更多收 ...
- CentOS 7 安装 MySql 8
1-安装 CentOS 7 2-安装 NETCORE SDK SDK 安装文档:https://dotnet.microsoft.com/download/linux-package-m ...