bzoj 3611: [Heoi2014]大工程 && bzoj 2286: [Sdoi2011消耗战
放波建虚树的模板。
大概是用一个栈维护根节点到当前关键点的一条链,把其他深度大于lca的都弹出去。
每次做完记得复原。
还有sort的时候一定要加cmp!!!
bzoj 3611
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 1000005
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
inline int read()
{
int p=;char c=getchar();
while(c<''||c>'')c=getchar();
while(c>=''&&c<='')p=p*+c-'',c=getchar();
return p;
}
int n;
int dfn[N];
int fa[N][];
int dep[N],z;
int head[N],ver[N*],nxt[N*],tot;
void add(int a,int b)
{
tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;
}
void dfs(int x,int f)
{
dfn[x]=++z;
for(int i=head[x];i;i=nxt[i])
{
if(ver[i]==f)continue;
dep[ver[i]]=dep[x]+;
fa[ver[i]][]=x;
dfs(ver[i],x);
}
return ;
}
void lca()
{
for(int i=;i<=;i++)
{
for(int j=;j<=n;j++)
{
fa[j][i]=fa[fa[j][i-]][i-];
}
}return ;
}
int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
for(int i=;i>=;i--)if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
if(x==y)return x;
for(int i=;i>=;i--)
{
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];y=fa[y][i];
}
}
return fa[x][];
}
bool cmp(int x,int y)
{
return dfn[x]<dfn[y];
}
int now[N],cnt;
int st[N],top;
int dian[N],num;
int vis[N];
void build()
{
tot=;
st[]=;top=;
for(int i=;i<=cnt;i++)
{
if(now[i]==)continue;
int v=now[i];
int la=lca(st[top],v);
if(st[top]!=la)
{
while(top>=&&dep[st[top-]]>dep[la])
{
add(st[top-],st[top]);top--;
}
add(la,st[top]);top--;
if(st[top]!=la)st[++top]=la;
}
st[++top]=v;
}
while(top>=)add(st[top-],st[top]),top--;
}
ll ans1;
int ans2,ans3;
int size[N];
int mx1[N],mx2[N],mn1[N],mn2[N];
void dfs(int x)
{
dian[++num]=x;
if(vis[x])size[x]=;
else size[x]=;
mx1[x]=mx2[x]=;
mn1[x]=mn2[x]=inf;
for(int i=head[x];i;i=nxt[i])
{
int quan=dep[ver[i]]-dep[x];
dfs(ver[i]);
if(vis[ver[i]])mn1[ver[i]]=;
if(mn1[ver[i]]+quan<mn1[x])
{
mn2[x]=mn1[x];
mn1[x]=mn1[ver[i]]+quan;
}
else if(mn1[ver[i]]+quan<mn2[x])mn2[x]=mn1[ver[i]]+quan;
ans1+=(long long)size[ver[i]]*(cnt-size[ver[i]])*quan;
size[x]+=size[ver[i]];
if(mx1[ver[i]]+quan>mx1[x])
{
mx2[x]=mx1[x];
mx1[x]=mx1[ver[i]]+quan;
}
else if(mx1[ver[i]]+quan>mx2[x])mx2[x]=mx1[ver[i]]+quan;
}
if(vis[x])ans2=min(ans2,mn1[x]);
else ans2=min(ans2,mn1[x]+mn2[x]);
if(mx2[x])ans3=max(ans3,mx1[x]+mx2[x]);
else if(vis[x])ans3=max(ans3,mx1[x]);
}
int main()
{
n=read();
int t1,t2,t3,t4;
for(int i=;i<n;i++)
{
t1=read();t2=read();
add(t1,t2);add(t2,t1);
}
dep[]=;
dfs(,-);
lca();
int q,k;
q=read();
memset(head,,sizeof(head));
for(int i=;i<=q;i++)
{
ans1=;ans2=inf;ans3=;
k=read();cnt=k;num=;
for(int j=;j<=k;j++)now[j]=read(),vis[now[j]]=;
sort(now+,now+k+,cmp);
build();dfs();
for(int j=;j<=cnt;j++)vis[now[j]]=;
for(int j=;j<=num;j++)head[dian[j]]=;num=;
printf("%lld %d %d\n",ans1,ans2,ans3);
}
return ;
}
bzoj2286
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 500005
#define inf 0x3f3f3f3f
using namespace std;
int n;
int head[N],ver[N*],nxt[N*],quan[N*],tot;
inline int read()
{
int p=;char c=getchar();
while(c<''||c>'')c=getchar();
while(c>=''&&c<='')p=p*+c-'',c=getchar();
return p;
}
void add(int a,int b,int c)
{
tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;quan[tot]=c;
}
int fa[N][],mn[N][],dep[N];
void lca()
{
for(int i=;i<=;i++)
{
for(int j=;j<=n;j++)
{
fa[j][i]=fa[fa[j][i-]][i-];
mn[j][i]=min(mn[j][i-],mn[fa[j][i-]][i-]);
}
}
return ;
}
int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
for(int i=;i>=;i--)if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
if(x==y)return x;
for(int i=;i>=;i--)
{
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];y=fa[y][i];
}
}
return fa[x][];
}
int z,dfn[N];
void dfs(int x,int f)
{
dfn[x]=++z;
for(int i=head[x];i;i=nxt[i])
{
if(ver[i]==f)continue;
dep[ver[i]]=dep[x]+;
fa[ver[i]][]=x;
mn[ver[i]][]=quan[i];
dfs(ver[i],x);
}return ;
}
int now[N],cnt;
int vis[N],st[N],top;
int dian[N],num;
int qur(int x,int y)
{
int ans=inf;
for(int i=;i>=;i--)
{
if(dep[fa[x][i]]>=dep[y])
{
ans=min(ans,mn[x][i]);
x=fa[x][i];
}
}
return ans;
}
void build()
{
tot=;
st[]=;top=;
for(int i=;i<=cnt;i++)
{
if(now[i]==)continue;
int v=now[i];
int la=lca(st[top],v);
if(la!=st[top])
{
while(top>=&&dep[st[top-]]>dep[la])
{
add(st[top-],st[top],qur(st[top],st[top-])),top--;
}
add(la,st[top],qur(st[top],la));top--;
if(la!=st[top])st[++top]=la;
}
st[++top]=v;
}
while(top>=)
{
add(st[top-],st[top],qur(st[top],st[top-])),top--;
}
return ;
}
long long f[N];
bool cmp(int x,int y)//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
{
return dfn[x]<dfn[y];
}
void dp(int x)
{
dian[++num]=x;f[x]=;
for(int i=head[x];i;i=nxt[i])
{
dp(ver[i]);
if(vis[ver[i]])f[x]+=quan[i];
else f[x]+=min((long long)quan[i],f[ver[i]]);
}
return ;
}
int main()
{
n=read();
int t1,t2,t3,t4;
for(int i=;i<n;i++)
{
t1=read();t2=read();t3=read();
add(t1,t2,t3);add(t2,t1,t3);
}
mn[][]=inf;dep[]=;
dfs(,-);
lca();
memset(head,,sizeof(head));
int q,k;
q=read();
for(int i=;i<=q;i++)
{
k=read();cnt=k;num=;
for(int j=;j<=k;j++)
{
now[j]=read();vis[now[j]]=;
}
sort(now+,now+k+,cmp);build();
dp();
printf("%lld\n",f[]);
for(int j=;j<=k;j++)vis[now[j]]=;
for(int j=;j<=num;j++)head[dian[j]]=;
}
return ;
}
bzoj 3611: [Heoi2014]大工程 && bzoj 2286: [Sdoi2011消耗战的更多相关文章
- bzoj 3611 [Heoi2014]大工程(虚树+DP)
3611: [Heoi2014]大工程 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 408 Solved: 190[Submit][Status] ...
- bzoj 3611: [Heoi2014]大工程 虚树
题目: 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 ...
- bzoj 3611[Heoi2014]大工程 虚树+dp
题意: 给一棵树 每次选 k 个关键点,然后在它们两两之间 新建 C(k,2)条 新通道. 求: 1.这些新通道的代价和 2.这些新通道中代价最小的是多少 3.这些新通道中代价最大的是多少 分析:较常 ...
- bzoj 3611: [Heoi2014]大工程
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...
- BZOJ.3611.[HEOI2014]大工程(虚树 树形DP)
题目链接 要求的和.最大值.最小值好像都可以通过O(n)的树形DP做,总询问点数<=2n. 于是建虚树就可以了.具体DP见DP()函数,维护三个值sum[],mx[],mn[]. sum[]要开 ...
- BZOJ 3611 [Heoi2014]大工程 ——虚树
虚树第二题.... 同BZOJ2286 #include <map> #include <cmath> #include <queue> #include < ...
- 3611: [Heoi2014]大工程
3611: [Heoi2014]大工程 链接 分析: 树形dp+虚树. 首先建立虚树,在虚树上dp. dp:sum[i]为i的子树中所有询问点之间的和.siz[i]为i的子树中有多少询问点,mn[i] ...
- BZOJ2286 [Sdoi2011]消耗战 和 BZOJ3611 [Heoi2014]大工程
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6371 Solved: 2496[Submit][Statu ...
- [Bzoj3611][Heoi2014]大工程(虚树)
3611: [Heoi2014]大工程 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 2000 Solved: 837[Submit][Status ...
随机推荐
- LAXCUS大数据操作系统3.03版本发布,欢迎使用试用
LAXCUS大数据操作系统3.03正式发布,欢迎下载使用试用.LAXCUS大数据操作系统,集成虚拟化.大数据.数据库.容器.中间件的多集群多用户多任务全栈通用系统软件,运行.开发.维护管理为一体的平台 ...
- truffle Dapp 搭建
安装truffle $ npm install -g truffle 依赖环境 NodeJS 访问https://nodejs.org 官方网站下载安装 系统:Windows, Linux or Ma ...
- scrapy有用的(代理,user-agent,随机延迟等)
代理 方法一(待测试) 见scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware import os # 设置相应的代理用户名密码,主机和 ...
- Java将json字符串转成map
Map<String, Object> map = (Map<String, Object>) JSONUtils.parse(result)
- 作业MathExam
MathExam233 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 600 650 • ...
- Pytorch相关内容
---恢复内容开始--- Pytorch中文官方文档:https://pytorch-cn.readthedocs.io/zh/latest/package_references/torch-nn P ...
- 【OSG】将显示的图形窗口化
窗口化原理 有时为了方便控制场景渲染,需要设置一个合适的图形环境窗口(即窗口化). 创建图形环境的主要步骤如下: (1)通过WindowingSystemInterface类得到系统窗口接口,该系统接 ...
- [转]让opencv输出人脸检测的得分(置信率)
转自:http://www.cnblogs.com/sciencefans/ 作者:sciencefans 最近项目略多,其中一个需要找出一些和脸比较像但是不是脸的负样本,想用opencv的人脸检测器 ...
- VMWare之——宿主机与虚拟机互相ping通,宿主机ping通另一台机器的虚拟机
版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明出处:http://blog.csdn.NET/l1028386804/article/details/52267554 今天给大家带来 ...
- 字符串拆分函数 func_splitstr
create type str_split is table of varchar2(4000) ; 1 CREATE OR REPLACE FUNCTION splitstr(p_string IN ...