CF1120D(神奇的构造+最小生成树)
考虑把树展开,单独把叶子节点拿出来
于是可以把控制点\(x\)的,抽象成是在它叶子节点间连权值为\(c_x\)的边
显然只用在\(x\)子树的最左边的叶子节点和最右边的叶子节点的下一个节点连边(最后一个叶子节点的下一个节点为 \(n+1\)),跑最小生成树即可
正确性证明的话,设叶子节点的权值分别为\(x_1,x_2……x_n\),做差分\(y_i=x_{i+1}-x_i\),显然\(\sum \limits _{i=1}^n y_i =0\)
正确性的话,感性理解一下吧QAQ,有理有据的感性理解
代码:
//OwO
#include <bits/stdc++.h>
#define N 200010
#define rep(i,x,y) for(i=x;i<=y;++i)
#define add(x,y) g[x].push_back(y)
#define ll long long
#define pii pair<int,int>
using namespace std;
ll c[N];
int dfn[N],sz[N],cnt,tot,fa[N],qwq[N],l[N],r[N],rr[N],n,lf=0;
vector<int> g[N];
struct ed{
int u,v,p;
ll w;
bool operator <(const ed &x)const{ return w<x.w; }
}e[N];
void ADD(int u,int v,int p,ll w){ e[++cnt]=(ed){u,v,p,w}; }
pii dfs(int x,int fa){
pii lst;
int pl=0;
if(g[x].size()<=1 && x!=1) l[x]=r[x]=++lf;
for(int i=0;i<g[x].size();++i){
int to=g[x][i];
if(to!=fa){
pii tmp=dfs(to,x);
l[x]=min(l[x],tmp.first);
r[x]=max(r[x],tmp.second);
}
}
return make_pair(l[x],r[x]);
}
int find(int x){ return (fa[x]==x)?x:fa[x]=find(fa[x]); }
ll solve1(){
int i;ll ans=0;
rep(i,1,cnt){
int u=find(e[i].u),v=find(e[i].v);
if(u==v) continue;
if(u>v) swap(u,v);
fa[v]=u;
ans+=e[i].w;
}
return ans;
}
void solve2(){
int i,nxt,j;tot=0;
rep(i,1,n+1) fa[i]=i;
for(i=1;i<=cnt;i=nxt){
for(j=i;e[j].w==e[i].w;++j){
int u=find(e[j].u),v=find(e[j].v);
if(u!=v) qwq[++tot]=e[j].p;
}
nxt=j;
for(j=i;e[j].w==e[i].w;++j){
int u=find(e[j].u),v=find(e[j].v);
if(u>v) swap(u,v);
if(u!=v) fa[v]=u;
}
}
}
int main(){
int i,x,y;
scanf("%d",&n);
rep(i,1,n) scanf("%I64d",&c[i]),fa[i]=i;fa[n+1]=n+1;
rep(i,1,n-1){
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
memset(l,0x3f,sizeof(l));
memset(r,0,sizeof(r));
dfs(1,0);rr[1]=n+1;
rep(i,1,n) ADD(l[i],r[i]+1,i,c[i]);
sort(e+1,e+cnt+1);
cout<<solve1()<<" ";
solve2();
sort(qwq+1,qwq+tot+1);
cout<<tot<<endl;
rep(i,1,tot) printf("%d ",qwq[i]);
}
CF1120D(神奇的构造+最小生成树)的更多相关文章
- Kruskal算法构造最小生成树
Kruskal算法来构造最小生成树,我总结了分为以下步骤: (1)建图,构造Kruskal边集,边集元素应该包括该边的起始顶点.终止顶点.权值: (2)将边集按权值从小到大的顺序进行排序: (3)从小 ...
- c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树
c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树 最小生成树(Minimum Cost Spanning Tree)的概念: 假设要在n个城市之间建立公路,则连通n个城市只需要n-1条线路 ...
- c/c++ 用普利姆(prim)算法构造最小生成树
c/c++ 用普利姆(prim)算法构造最小生成树 最小生成树(Minimum Cost Spanning Tree)的概念: 假设要在n个城市之间建立公路,则连通n个城市只需要n-1条线路.这时 ...
- 图的建立(邻接矩阵)+深度优先遍历+广度优先遍历+Prim算法构造最小生成树(Java语言描述)
主要参考资料:数据结构(C语言版)严蔚敏 ,http://blog.chinaunix.net/uid-25324849-id-2182922.html 代码测试通过. package 图的建 ...
- MST性质(用于构造最小生成树)
描述:假设N=(V,{E})是一个连通网,U是顶点集V的一个非空子集.若(u,v)是一条具有最小权值(代价)的边,其中u∈U,v∈V-U,则必存在一棵包含边(u,v)的最小生成树. 证明: 假设网N的 ...
- 数据结构-图-Java实现:有向图 图存储(邻接矩阵),最小生成树,广度深度遍历,图的连通性,最短路径1
import java.util.ArrayList; import java.util.List; // 模块E public class AdjMatrixGraph<E> { pro ...
- CSU 1116 Kingdoms(枚举最小生成树)
题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1116 解题报告:一个国家有n个城市,有m条路可以修,修每条路要一定的金币,现在这个国家只 ...
- poj1251 最小生成树
Description The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid ...
- ACM: meixiuxiu学图论-并查集-最小生成树-解题报告
/* 最小生成树,最小环的最大权值按照排序后去构建最小生成树就可以了,注意遇到的第一个根相同的点就记录权值,跳出,生成的环就是最小权值环. */ //AC代码: #include"iostr ...
随机推荐
- 章节九、4-ChromDriver介绍
一.首先下载Chrom浏览器驱动,将驱动解压到存放火狐浏览器驱动文件路径中(请观看前面的章节) 1.进入该网址下载匹配本地浏览器版本的驱动 http://chromedriver.storage.go ...
- uiautomatorviewer 查看元素报错: Error taking device screenshot: null 原因
使用uiautomatorviewer 查看android某些页面元素,出现错误Error obtaining UI hierarchy Reason: Error taking device sc ...
- SQL Server中LIKE %search_string% 走索引查找(Index Seek)浅析
在SQL Server的SQL优化过程中,如果遇到WHERE条件中包含LIKE '%search_string%'是一件非常头痛的事情.这种情况下,一般要修改业务逻辑或改写SQL才能解决SQL执行 ...
- mssql sqlserver 索引专题
摘要: 下文将详细讲述sql server 索引的相关知识,如下所示: 实验环境: sql server 2008 R2 sqlserver索引简介: mssql sqlsever 索引分类简介 ms ...
- SQL server 远程连接不成功解决
一直以来打算自己做一个博客网站,前段时间开始准备做了,正好碰上新睿云服务器免费一年的活动,赶紧拿下.装好了sqlserver ,用本地访问没有问题,但是关键是外网访问一直不行找了好多资料最终才搞定.下 ...
- Windows 更快捷方便的安装软件,命令提示符上安装 Chocolatey
在命令提示符上安装 Chocolatey @powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-o ...
- Django中的信号
信号 Django 提供一个“信号分发器”,允许解耦的应用在框架的其它地方发生操作时会被通知到. 简单来说,信号允许特定的sender通知一组receiver某些操作已经发生. 这在多处代码和同一事件 ...
- 上传本地文件到GitHub上
问题解决 今天在windows上上传本地文件到github,出现用户名和仓库不匹配的情况,解决方式如下: 打开控制面板,选择用户账户 把该删除的账户删除一下就行了. 上传文件的步骤如下: 将上传的文件 ...
- 构建高性能服务 Java高性能缓冲设计 vs Disruptor vs LinkedBlockingQueue
一个仅仅部署在4台服务器上的服务,每秒向Database写入数据超过100万行数据,每分钟产生超过1G的数据.而每台服务器(8核12G)上CPU占用不到100%,load不超过5.这是怎么做到呢?下面 ...
- .net core 的图片处理及二维码的生成及解析
写代码这事,掐指算来已经十有余年. 从html到css到javascript到vbscript到c#,从兴趣到职业,生活总是失落与惊喜并存. 绝大部分时候,出发并不是因为知道该到哪里去,只是知道不能再 ...