[洛谷]P3729 曼哈顿计划EX(最小割树/等价流树)
题目大意:给出一张n个点m条边的无向图,每个点有点权,q次询问,每次给出k,要求选出若干个点点权之和不小于k,求一个最大的值x,使得选出的点中任意两点之间至少有x条互不相交的链。(n<=550,m<=3000,q<=2017)
当时看到这题一看就不可做 看了题解说什么等价流树也看不懂 后来FallDream大佬做了一题最小割树 看了看网上大神极短的说明加上自己大量的脑补终于搞懂了这玩意儿 另外貌似等价流树就是最小割树
最小割树的思路大概是先任意求出两点之间的最小割,并把整张图按最小割分成两个部分,并用这个最小割更新所有被分到不同部分的点对之间的最小割,然后对分出的两个部分分治,值得注意的是即使点集被分治分小了,每次我们更新答案仍然要更新整张图。
通过这个分治过程,我们会得到n-1个最小割,并能组成一个树形结构,每次求两点之间最小割时,两点之间连边,边权为最小割,图上任意两点之间的最小割就是树上路径的最小值,这样我们只要做O(n)次网络流就能求出O(n^2)个点对之间的最小割。
下面考虑这题,两点之间至少有x条不相交的链就是说最大流/最小割大等x,假设我们选出了若干个点,那么这些点两两之间最小割的最小值,就是在等价流树上要让这些点连通所必要的边的最小值,我们把等价流树上的边从大到小加进带权并查集,维护各个连通块的权值和,问题即可解决。
自己乱写了一个比较舒服的模板。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
inline int read()
{
int x;char c;
while((c=getchar())<''||c>'');
for(x=c-'';(c=getchar())>=''&&c<='';)x=x*+c-'';
return x;
}
#define MN 550
#define MM 3000
#define INF 0x7FFFFFFF
struct edge{int nx,t,w;}e[MM*+];
int m,S,T,h[MN+],en,d[MN+],q[MN+],qn,c[MN+];
int w[MN+],uu[MM+],vv[MM+],cnt,f[MN+],ans[MM+];
vector<int> v[MN+];
struct tredge{int u,v,w;}t[MN+];
bool cmp(tredge a,tredge b){return a.w>b.w;}
struct query{int k,id;}r[MM+];
bool cmpk(query a,query b){return a.k<b.k;}
int gf(int k){return f[k]?f[k]=gf(f[k]):k;}
inline void ins(int x,int y)
{
e[++en]=(edge){h[x],y,};h[x]=en;
e[++en]=(edge){h[y],x,};h[y]=en;
}
bool bfs()
{
int i,j;
memset(d,,sizeof(d));
for(d[q[i=qn=]=S]=;i<=qn;++i)for(j=c[q[i]]=h[q[i]];j;j=e[j].nx)
if(e[j].w&&!d[e[j].t])d[q[++qn]=e[j].t]=d[q[i]]+;
return d[T];
}
int dfs(int x,int r)
{
if(x==T)return r;
int k,u=;
for(int&i=c[x];i;i=e[i].nx)if(e[i].w&&d[x]+==d[e[i].t])
{
k=dfs(e[i].t,min(r-u,e[i].w));
u+=k;e[i].w-=k;e[i^].w+=k;
if(u==r)return u;
}
return d[x]=,u;
}
void color(int x)
{
c[x]=;
for(int i=h[x];i;i=e[i].nx)
if(e[i].w&&!c[e[i].t])color(e[i].t);
}
void build(int x)
{
if(v[x].size()<)return;
t[++cnt].u=S=x;t[cnt].v=T=v[x][v[x][]==x];
memset(h,,sizeof(h));en=;
for(int i=;i<=m;++i)ins(uu[i],vv[i]);
while(bfs())t[cnt].w+=dfs(S,INF);
memset(c,,sizeof(c));
color(x);
for(int i=;i<v[x].size();++i)while(i<v[x].size()&&!c[v[x][i]])
v[T].push_back(v[x][i]),v[x].erase(v[x].begin()+i);
build(T);build(x);
}
int main()
{
int n,q,i,j,k=;
n=read();m=read();q=read();
for(i=;i<=n;++i)k=max(k,w[i]=read()),v[].push_back(i);
for(i=;i<=m;++i)uu[i]=read(),vv[i]=read();
for(i=;i<=q;++i)r[i]=(query){read(),i};
build();
sort(r+,r+q+,cmpk);
sort(t+,t+n,cmp);
for(j=;j<=q&&r[j].k<=k;++j)ans[r[j].id]=INF;
for(i=;i<n;++i)
{
k=max(k,w[gf(t[i].u)]+=w[gf(t[i].v)]);
f[gf(t[i].v)]=gf(t[i].u);
for(;j<=q&&r[j].k<=k;++j)ans[r[j].id]=t[i].w;
}
for(i=;i<=q;++i)
if(ans[i]==INF)puts("nan");
else if(ans[i])printf("%d\n",ans[i]);
else puts("Nuclear launch detected");
}
[洛谷]P3729 曼哈顿计划EX(最小割树/等价流树)的更多相关文章
- 【洛谷P3329】 [ZJOI2011]最小割(最小割树)
洛谷 题意: 给出一个无向图,之后有\(q,q\leq 30\)组询问,每组询问有一个\(x\),回答有多少点对\((a,b)\)其\(a-b\)最小割不超过\(x\). 思路: 这个题做法要最小割树 ...
- 洛谷P4014 分配问题【最小/大费用流】题解+AC代码
洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...
- ACM/ICPC 之 伞兵-最小割转最大流(POJ3308)
//以行列建点,伞兵位置为单向边-利用对数将乘积转加法 //最小割转最大流 //Time:63Ms Memory:792K #include<iostream> #include<c ...
- 【Luogu】P2057善意的投票(最小割转最大流)
题目链接 也算水题一道吧,不过Round1感性理解一下就xjb建了个图,40 Round2仔细分析了一会,理性建了个图,90 然后分析了半天……改大数组就A了…… 从S到所有值为1的点连一条inf的边 ...
- 洛谷P4299 首都(BZOJ3510)(LCT,树的重心,二分查找)
Update:原来的洛谷U21715已成坑qwq 已经被某位管理员巨佬放进公共题库啦!又可以多一个AC记录啦! 洛谷题目传送门 其实也可以到这里交啦 思路分析 动态维护树的重心 题目中说到国家的首都会 ...
- [NOI导刊2010提高&洛谷P1774]最接近神的人 题解(树状数组求逆序对)
[NOI导刊2010提高&洛谷P1774]最接近神的人 Description 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某 ...
- 洛谷P3380 【模板】二逼平衡树(树套树)(线段树+树状数组)
P3380 [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数 ...
- 【BZOJ2595_洛谷4294】[WC2008]游览计划(斯坦纳树_状压DP)
上个月写的题qwq--突然想写篇博客 题目: 洛谷4294 分析: 斯坦纳树模板题. 简单来说,斯坦纳树问题就是给定一张有边权(或点权)的无向图,要求选若干条边使图中一些选定的点连通(可以经过其他点) ...
- 洛谷 P3380 【模板】二逼平衡树(树套树)-线段树套splay
P3380 [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数 ...
随机推荐
- 团队作业7——Beta版本冲刺计划及安排
上一个阶段的总结: 在Alpha阶段,我们小组已近完成了大部分的功能要求,小组的每一个成员都发挥了自己的用处.经过了这么久的磨合,小组的成员之间越来越默契,相信在接下来的合作中,我们的开发速度会越来越 ...
- display属性
display 属性规定元素应该生成的框的类型. 值 描述 none 此元素不会被显示. block 此元素将显示为块级元素,此元素前后会带有换行符. inline 默认.此元素会被显示为内联元素,元 ...
- linux系统命令学习系列-用户组管理
先复习一下上节内容: 设置密码命令passwd 用户信息修改命令usermod 用户删除命令userdel 作业:修改user1的用户id为505,家目录到admin,用户组为admin,最后删除us ...
- angular2 学习笔记 ( 第3方插件 jQuery and ckeditor )
refer : https://forums.meteor.com/t/importing-ckeditor-using-npm/28919/2 (ckeditor) https://github ...
- Docker学习笔记 - Docker的远程访问
学习内容: 配置客户端与守护进程的远程访问 服务端配置-H选项: 使服务端支持远程被访问 客户端使用-H选项: 使客户端访问远程服务端 本地环境DOCKER_HOST设置客户端访问的默认服务端地址 准 ...
- Spark入门(1-1)什么是spark,spark和hadoop
一.Spark是什么? Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎,可用来构建大型的.低延迟的数据分析应用程序. Spark是UC Berkeley AMP lab (加 ...
- C#实现导出Excel
这段时间用到了导出Excel的功能,这个功能还是比较常用的,我常用的有两个方法,现在整理一下,方便以后查看. 一.实现DataTable数据导出到本地,需要自己传进去导出的路径. /// <su ...
- django的models模块查询方法
假定models中有一个类BookInfo 模块查询不同于sql语句,模块查询的结果会返回符合条件的整个一行的对象,或者多个对象组成的查询集. 查询集类似列表,有相似的方法. 1 model查询语句: ...
- 【Vue中的swiper轮播组件】
<template> <swiper :options="swiperOption" ref="mySwiper"> <!-- s ...
- 集合之深入理解HashMap
Hashmap是一种非常常用的.应用广泛的数据类型 1.hashmap的数据结构 要知道hashmap是什么,首先要搞清楚它的数据结构,在java编程语言中,最基本的结构就是两种,一个是数组,另外一个 ...