bzoj 3206: [Apio2013]道路费用【最小生成树+并查集】
参考:http://hzwer.com/6888.html
把k条道路权值设为0,和其他边一起跑MST,然后把此时选中的其他边设为必选,在新图中加上必选变缩成k个点,把所有边重标号,枚举k跳边的选取情况,和其他边做MST,建出树,k条边的权值在树上取min
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=300005,inf=1e9;
int n,m,k,top,cnt,s,f[N],fa[N],p[N],po[N],de[N],h[N],mn[N];
long long va[N],sum[N],ans;
bool mk[N];
struct qwe
{
int ne,to;
}e[N];
struct bian
{
int u,v,w;
}a[N],b[25],q[N];
bool cmp(const bian &a,const bian &b)
{
return a.w<b.w;
}
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
inline void add(int u,int v)
{
cnt++;
e[cnt].ne=h[u];
e[cnt].to=v;
h[u]=cnt;
}
inline void ins(int u,int v)
{
add(u,v);
add(v,u);
}
inline int zhao(int x)
{
return x==fa[x]?x:fa[x]=zhao(fa[x]);
}
inline int zh(int x)
{
return x==f[x]?x:f[x]=zh(f[x]);
}
void dp(int u)
{
sum[u]=va[u];
for(int i=h[u];i;i=e[i].ne)
if(e[i].to!=f[u])
{
de[e[i].to]=de[u]+1;
f[e[i].to]=u;
dp(e[i].to);
sum[u]+=sum[e[i].to];
}
}
void wk()
{
cnt=0;
for(int i=1;i<=k+1;i++)
{
int p=po[i];
h[p]=f[p]=0;
fa[p]=p,mn[p]=inf;
}
for(int i=1;i<=k;i++)
if(mk[i])
{
int fu=zhao(b[i].u),fv=zhao(b[i].v);
if(fu==fv)
return;
fa[fu]=fv;
ins(b[i].u,b[i].v);
}
for(int i=1;i<=k;i++)
{
int fu=zhao(q[i].u),fv=zhao(q[i].v);
if(fu!=fv)
{
fa[fu]=fv;
ins(q[i].u,q[i].v);
}
}
dp(s);
for(int i=1;i<=k;i++)
{
int u=q[i].u,v=q[i].v;
if(de[u]>de[v])
swap(u,v);
while(de[u]!=de[v])
mn[v]=min(mn[v],q[i].w),v=f[v];
while(u!=v)
{
mn[v]=min(mn[v],q[i].w);
mn[u]=min(mn[u],q[i].w);
u=f[u],v=f[v];
}
}
long long con=0;
for(int i=1;i<=k;i++)
if(mk[i])
{
int u=b[i].u,v=b[i].v;
if(de[u]>de[v])
swap(u,v);
con+=mn[v]*sum[v];
}
ans=max(ans,con);
}
void dfs(int x)
{
if(x==k+1)
{
wk();
return;
}
mk[x]=0;
dfs(x+1);
mk[x]=1;
dfs(x+1);
}
int main()
{
n=read(),m=read(),k=read();
for(int i=1;i<=m;i++)
a[i].u=read(),a[i].v=read(),a[i].w=read();
sort(a+1,a+1+m,cmp);
for(int i=1;i<=k;i++)
b[i].u=read(),b[i].v=read();
for(int i=1;i<=n;i++)
p[i]=read();
for(int i=1;i<=n;i++)
fa[i]=f[i]=i;
for(int i=1;i<=k;i++)
fa[zhao(b[i].u)]=zhao(b[i].v);
for(int i=1;i<=m;i++)
{
int u=a[i].u,v=a[i].v;
if(zhao(u)!=zhao(v))
{
fa[zhao(u)]=fa[zhao(v)];
f[zh(u)]=f[zh(v)];
}
}
s=zh(1);
for(int i=1;i<=n;i++)
{
int z=zh(i);
va[z]+=p[i];
if(z==i)
po[++po[0]]=i;
}
for(int i=1;i<=k;i++)
b[i].u=zh(b[i].u),b[i].v=zh(b[i].v);
for(int i=1;i<=m;i++)
a[i].u=zh(a[i].u),a[i].v=zh(a[i].v);
for(int i=1;i<=m;i++)
{
int fu=zh(a[i].u),fv=zh(a[i].v);
if(fu!=fv)
mk[i]=1,f[fu]=fv;
}
for(int i=1;i<=m;i++)
if(mk[i])
q[++top]=a[i];
dfs(1);
printf("%lld\n",ans);
return 0;
}
bzoj 3206: [Apio2013]道路费用【最小生成树+并查集】的更多相关文章
- [BZOJ3206][APIO2013]道路费用(最小生成树)
3206: [Apio2013]道路费用 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 568 Solved: 266[Submit][Status ...
- [Bzoj3206][Apio2013]道路费用(kruscal)(缩点)
3206: [Apio2013]道路费用 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 536 Solved: 252[Submit][Status ...
- CSP 201703-4 地铁修建【最小生成树+并查集】
问题描述 试题编号: 201703-4 试题名称: 地铁修建 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市 ...
- UVA 1395 苗条的生成树(最小生成树+并查集)
苗条的生成树 紫书P358 这题最后坑了我20分钟,怎么想都对了啊,为什么就wa了呢,最后才发现,是并查集的编号搞错了. 题目编号从1开始,我并查集编号从0开始 = = 图论这种题真的要记住啊!!题目 ...
- BZOJ 4569 [Scoi2016]萌萌哒 | ST表 并查集
传送门 BZOJ 4569 题解 ST表和并查集是我认为最优雅(其实是最好写--)的两个数据结构. 然鹅!他俩加一起的这道题,我却--没有做出来-- 咳咳. 正解是这样的: 类似ST表有\(\log ...
- 洛谷P3639 [APIO2013] 道路费用 [生成树的特殊算法]
题目传送门 道路费用 格式难调,题面就不放了. 分析: 这是一道要细(yan)心(jing)的生成树的好(gui)题. 首先我们看到$k$的范围非常小,那么我们就可以直接$2^k$枚举每一条加边是否选 ...
- bzoj 3559: [Ctsc2014]图的分割【最小生成树+并查集】
读题两小时系列-- 在读懂题意之后,发现M(c)就是c这块最大权割边也就是的最小生成树的最大权边的权值,所以整个问题都可以在MST的过程中解决(M和c都是跟着并查集变的) 不过不是真的最小生成树,是合 ...
- 题解 洛谷 P3639 【[APIO2013]道路费用 】
不难想到可以\(2^k\)去枚举\(k\)条新边的选择方案,然后加入原图中的边来使图连通,用当前方案的收益去更新答案,但是这样复杂度过不去. 可以先把\(k\)条新边都连上,然后再加入边权从小到大排序 ...
- 关于最小生成树(并查集)prime和kruskal
适合对并查集有一定理解的人. 新手可能看不懂吧.... 并查集简单点说就是将相关的2个数字联系起来 比如 房子 1 2 3 4 5 6 ...
随机推荐
- iOS 用cornerstone 创建分支
第一步:在cornerstone中添加服务器上的代码路径,如下: 第二步:选中服务器路径下的代码,选择“分支”按钮 第三步:开始创建分支 第四步:效果图如下 第五步:选择分支下的路径下载代码并进行修改 ...
- how to read openstack code: loading process
之前我们了解了neutron的结构,plugin 和 extension等信息.这一章我们看一下neutron如何加载这些plugin和extension.也就是neutron的启动过程.本文涉及的代 ...
- 使用SpringMVC @Async异步执行方法的笔记 (转载)
原文:http://blog.csdn.net/yuwenruli/article/details/8514393 测试代码: @RunWith(SpringJUnit4ClassRunner.cla ...
- 异步SOCKET分包和组包的一种通用算法
unit uPackage;// 应用协议// cxg 2016-9-23// 包=包头+包体 interface uses SysUtils, Classes, PeachCtrl.Net.Iocp ...
- Ajax系列之四:问题总结
1.最经典的就是ie下的缓存问题了. 假设使用的是get.那么在ie下出现缓存问题.导致代码仅仅运行一次. 解决的方法就是加时间戳或者随机数,使url变为唯一,这样就不会出现ie 下的缓存问题了, ...
- Linux OpenSSH后门的加入与防范
引言:相对于Windows,Linux操作系统的password较难获取.只是非常多Linuxserver配置了OpenSSH服务.在获取root权限的情况下,能够通过改动或者更新OpenSSH代码等 ...
- 将Python打印的内容进行高亮的输出
将打印的内容进行高亮的显示 内容: 格式: echo "\033[字背景颜色;字体颜色m字符串\033[0m" 例如: "\033[41;36m something he ...
- 关于Android中物理按键不响应的可能的一个问题。
今天在工作中犯了一个错误,写的视频播放器突然物理音量键就不起作用了. 一開始以为是自己定义的音量条把系统的物理音量条按键给屏蔽掉了. 删除自己定义的音量条还是不行,又怀疑是是加入了什么权限之类的.重复 ...
- 移动端html5页面长按实现高亮全选文本内容的兼容解决方式
近期须要给html5的WebAPP在页面上实现一个复制功能:用户点击长按文本会全选文字并弹出系统"复制"菜单.用户能够点击"复制"进行复制操作.然后粘贴到App ...
- 【iOS系列】-UIWebView加载网页禁止左右滑动
[iOS系列]-UIWebView加载网页禁止左右滑动 问题: 做项目时候,用UIWebView加载网页的时候,要求是和微信网页中打开的网页的效果一样,也即是只能上下滑动,不能左右滑动,也不能缩放. ...