考前随便做点水题愉♂悦身心 有助于退役

这题意思其实就是说要把外向基环树森林改成一个环的最小代价。

依照套路,先对每棵基环树的树做dp,这里因为要是环,要把所有的树都拆成链,然后连接。所以考虑以最小代价拆掉每一个树。

因为对于树的每层,只能选择出一个儿子作为链的部分保留下来,所以贪心的尽量选权值大的儿子留下来,其他的全部作为另一条链的开头准备接到环上。

所以树的部分就是一个简单的树形DP。

然后看环上的DP,相当于是要把我们之前搞出来的所有的链全部接上去,所以环上至少要有一个边断开,让这些链接上去。

所以环上,每条边要么把入点连着的链断开,接入环中某处,要么直接断掉这条边将一些链给接上去。

这时只要对环上每条边以这两种方案择优选取,最后发现最优方案如果没有环上边被断开,就强制找一个最小的代价让环上边断掉。

当图是一个基环树森林的时候,不影响正确性,我们需要让每棵树的环都断开一个,以互相接入成为环,所以每个基环树可以独立做。

不过注意一个特例:整个图就是一个环,这时就不需要断了。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define mst(x) memset(x,0,sizeof x)
#define dbg(x) cerr << #x << " = " << x <<endl
#define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=1e5+,INF=0x3f3f3f3f;
struct thxorz{
int head[N],nxt[N<<],to[N<<],tot;
thxorz(){tot=;}
inline void add(int x,int y){
to[++tot]=y,nxt[tot]=head[x],head[x]=tot;
to[++tot]=x,nxt[tot]=head[y],head[y]=tot;
}
}G;
ll ans;
int n;
#define y G.to[j]
int vis[N],lp[N],val[N],chain[N],m,lpfa,flag,rt;
void dfs(int x){//dbg(x);
vis[x]=;
for(register int j=G.head[x];j&&!flag;j=G.nxt[j])if(j&){//mistake:the direction of the edge!
if(vis[y])return lpfa=y,flag=,lp[m=]=x,void();
else{dfs(y);if(flag)lp[++m]=x;}
}
if(!flag)vis[x]=;
if(x==lpfa)flag=;
}
void dp(int x){//dbg(x);
vis[x]=;ll sum=;
for(register int j=G.head[x];j;j=G.nxt[j])if(!vis[y])dp(y),sum+=val[y],MAX(chain[x],val[y]);
ans+=sum-chain[x];
}
#undef y
int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
read(n);
for(register int i=,x;i<=n;++i)read(x),read(val[i]),G.add(x,i);
for(register int i=;i<=n;++i)if(!vis[i]){//dbg(i);
flag=,dfs(i);int chosen=;//dbg("ok");dbg(m);
if(m==n)break;
for(register int j=;j<=m;++j)dp(lp[j]);//dbg(lp[j]);
#define nxt (j+1>m?1:j+1)//attention to the order..
for(register int j=;j<=m;++j){
if(chain[lp[j]]<val[lp[nxt]])ans+=chain[lp[j]];
else ans+=val[lp[nxt]],chosen=;
}
if(!chosen){//dbg2(i,chosen);
int tmp=INF;
for(register int j=;j<=m;++j)MIN(tmp,-chain[lp[j]]+val[lp[nxt]]);
ans+=tmp;
}
}
printf("%lld\n",ans);
return ;
}

总结:这题也涉及一个断环的操作,不过是需要考察性质之后发现的,是一个不那么显然的题目。。。

luogu3651 展翅翱翔之时 (はばたきのとき)[基环树+贪心]的更多相关文章

  1. 洛谷P3656 展翅翱翔之时 (はばたきのとき)(洛谷2017.3月赛round1 t4)

    题目背景 船が往くよミライへ旅立とう 船只启航 朝未来展开旅途 青い空笑ってる(なにがしたい?) 湛蓝天空露出微笑(想做些什么?) ヒカリになろうミライを照らしたい 化作光芒吧 想就此照亮未来 輝きは ...

  2. 【洛谷P3651】展翅翱翔之时

    难以吐槽出题人的中二病…… 这题有点类似ZJOI2008 骑士,先跑树上的,最后拆环即可. #include<bits/stdc++.h> #define N 100005 typedef ...

  3. tyvj1940创世纪——贪心(基环树)

    题目:http://www.joyoi.cn/problem/tyvj-1940 基环树的样子,看了书上的讲解,准备写树上DP,然后挂了: #include<iostream> #incl ...

  4. 与图论的邂逅01:树的直径&基环树&单调队列

    树的直径 定义:树中最远的两个节点之间的距离被称为树的直径.  怎么求呢?有两种官方的算法(不要问官方指谁我也不晓得): 1.两次搜索.首先任选一个点,从它开始搜索,找到离它最远的节点x.然后从x开始 ...

  5. COCI2014/2015 Contest#1 D MAFIJA【基环树最大独立点集】

    T1725 天黑请闭眼 Online Judge:COCI2014/2015 Contest#1 D MAFIJA(原题) Label:基环树,断环+树形Dp,贪心+拓扑 题目描述 最近天黑请闭眼在 ...

  6. 【BZOJ1791】【IOI2008】【基环树】island(status第一速度)

      1791: [Ioi2008]Island 岛屿  Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 908  Solved: 159 [Su ...

  7. BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心

    BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心 Description 在计算机中,CPU只能和高速缓存Cache直接交换数据.当所需的内存单元不在Cache中时,则需要从主存里把数 ...

  8. 『Island 基环树直径』

    Island(IOI 2008) Description 你准备浏览一个公园,该公园由 N 个岛屿组成,当地管理部门从每个岛屿 i 出发向另外一个岛屿建了一座长度为 L_i 的桥,不过桥是可以双向行走 ...

  9. [Codeforces235D]Graph Game——概率与期望+基环树+容斥

    题目链接: Codeforces235D 题目大意:给出一棵基环树,并给出如下点分治过程,求点数总遍历次数的期望. 点分治过程: 1.遍历当前联通块内所有点 2.随机选择联通块内一个点删除掉 3.对新 ...

随机推荐

  1. JavaSE基础(十二)--Java 对象和类

    Java 对象和类 Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 重载 本节我们重点研究对象和类的概念. 对象:对象是类的一个实例(对象不是找个女朋友 ...

  2. Linux系列(14)之工作管理

    1.工作管理 说明:工作管理(job control)是用在bash环境下的,也就是说:“当我们登录系统取得bash shell之后,在单一终端机接口下同时进行多个工作的行为管理”.举例说明,我们在登 ...

  3. Centos7下永久修改mysql5.6最大连接数

    由于解除系统限制,设置最大连接数时,量力而行.https://blog.csdn.net/five3/article/details/79671317

  4. jupyter lab 安装

    在windows下安装jupyter 特别简单 首先你需要有Anaconda or python的环境变量,这里我就不说怎么安装环境变量了,网上一大堆教程 启动黑窗口,下载jupyter pip in ...

  5. 关于greenlet的一些问题

    今天测试关于协程方面的代码发现我安装了greenlet模块缺导入不进.如图: 后来找了半天才发现原来greenlet被整进了gevent包中,如下导入就可以成功: 但这个greenlet没有了swit ...

  6. linux下shell 脚本 中windows换行符换成linux换行符

    sed -i 's/\r//' filename window下默认是 \r\n linux下是\n unix下是\r

  7. 有趣的后渗透工具 Koadic

    koadic是DEFCON黑客大会上分享出来的的一个后渗透工具,虽然和msf有些相似,但是Koadic主要是通过使用Windows ScriptHost(也称为JScript / VBScript)进 ...

  8. C# Base64 操作类

    using System; using System.Text; namespace VWFC.IT.CUP.BLL.Util { /// <summary> /// Base64 too ...

  9. C#使用phantomjs,爬取AJAX加载完成之后的页面

    1.开发思路:入参根据apiSetting配置文件,分配静态文件存储地址,可实现不同站点的静态页生成功能.静态页生成功能使用无头浏览器生成,生成之后的字符串进行正则替换为固定地址,实现本地正常访问. ...

  10. shiro 权限过滤器 -------(1)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABBEAAAJRCAIAAACcEbhqAAAgAElEQVR4nO3dv67sVtkHYEefhIKUIC ...