题目大意:给出一张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(最小割树/等价流树)的更多相关文章

  1. 【洛谷P3329】 [ZJOI2011]最小割(最小割树)

    洛谷 题意: 给出一个无向图,之后有\(q,q\leq 30\)组询问,每组询问有一个\(x\),回答有多少点对\((a,b)\)其\(a-b\)最小割不超过\(x\). 思路: 这个题做法要最小割树 ...

  2. 洛谷P4014 分配问题【最小/大费用流】题解+AC代码

    洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...

  3. ACM/ICPC 之 伞兵-最小割转最大流(POJ3308)

    //以行列建点,伞兵位置为单向边-利用对数将乘积转加法 //最小割转最大流 //Time:63Ms Memory:792K #include<iostream> #include<c ...

  4. 【Luogu】P2057善意的投票(最小割转最大流)

    题目链接 也算水题一道吧,不过Round1感性理解一下就xjb建了个图,40 Round2仔细分析了一会,理性建了个图,90 然后分析了半天……改大数组就A了…… 从S到所有值为1的点连一条inf的边 ...

  5. 洛谷P4299 首都(BZOJ3510)(LCT,树的重心,二分查找)

    Update:原来的洛谷U21715已成坑qwq 已经被某位管理员巨佬放进公共题库啦!又可以多一个AC记录啦! 洛谷题目传送门 其实也可以到这里交啦 思路分析 动态维护树的重心 题目中说到国家的首都会 ...

  6. [NOI导刊2010提高&洛谷P1774]最接近神的人 题解(树状数组求逆序对)

    [NOI导刊2010提高&洛谷P1774]最接近神的人 Description 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某 ...

  7. 洛谷P3380 【模板】二逼平衡树(树套树)(线段树+树状数组)

    P3380 [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数 ...

  8. 【BZOJ2595_洛谷4294】[WC2008]游览计划(斯坦纳树_状压DP)

    上个月写的题qwq--突然想写篇博客 题目: 洛谷4294 分析: 斯坦纳树模板题. 简单来说,斯坦纳树问题就是给定一张有边权(或点权)的无向图,要求选若干条边使图中一些选定的点连通(可以经过其他点) ...

  9. 洛谷 P3380 【模板】二逼平衡树(树套树)-线段树套splay

    P3380 [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数 ...

随机推荐

  1. C语言总结报告

    1.当初你是如何做出选择计算机专业的决定的? 经过一个学期,你的看法改变了么,为什么? 你觉得计算机是你喜欢的领域吗,它是你擅长的领域吗? 为什么? 当初报考计算机专业,是看到计算机专业在当今社会有良 ...

  2. 201621123062《java程序设计》第14周作业总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结与数据库相关内容. 思维导图: 2. 使用数据库技术改造你的系统 2.1 简述如何使用数据库技术改造你的系统.要建立什么表?截图你的 ...

  3. 项目Beta冲刺Day3

    项目进展 李明皇 今天解决的进度 完善了程序的运行逻辑(消息提示框等) 明天安排 前后端联动调试 林翔 今天解决的进度 向微信官方申请登录验证session以维护登录态 明天安排 继续完成维护登录态 ...

  4. 2017 国庆湖南 Day5

    期望得分:76+80+30=186 实际得分:72+10+0=82 先看第一问: 本题不是求方案数,所以我们不关心 选的数是什么以及的选的顺序 只关心选了某个数后,对当前gcd的影响 预处理 cnt[ ...

  5. Android广播发送失败

    现在至今为止Android 8.0 不支持大部分广播收发 如果无法使用建议换至Android 7.0版本 且 minSdkVersion 24

  6. JAVA_SE基础——52.匿名内部类

    电信的电箱烧了,害我断了2天网,真拿命,耽误了 Java匿名内部类的总结: 没有名字的内部类.就是内部类的简化形式.一般只用一次就可以用这种形式.匿名内部类其实就是一个匿名子类对象.想要定义匿名内部类 ...

  7. Windows中添加自己的程序到开机启动中(添加服务,添加注册表)

    在系统启动的时候启动自己想要启动的程序: 方法一:利用开机启动文件夹 将exe文件或exe文件的快捷方式复制到(启动)文件夹下 以win7为例:开始→所有程序→启动→鼠标右键打开 方法二:添加系统服务 ...

  8. typedef 使用

    1,C 语言提供了 typedef 关键字,您可以使用它来为类型取一个新的名字. #include<stdio.h> typedef unsigned char BYTE; int mai ...

  9. 修改了SpringBoot的主类名称后,gradle build报错的解决办法

    Unable to find a single main class from the following candidates [*.*Application]

  10. HTTP协议扫盲(一)HTTP协议的基本概念和通讯原理

    一.HTTP协议的概念 1.引子  - 从url开始 URL(Uniform Resource Locator) 地址用于描述一个网络上的资源, 基本格式如下 schema://host[:port# ...