放波建虚树的模板。

大概是用一个栈维护根节点到当前关键点的一条链,把其他深度大于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消耗战的更多相关文章

  1. bzoj 3611 [Heoi2014]大工程(虚树+DP)

    3611: [Heoi2014]大工程 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 408  Solved: 190[Submit][Status] ...

  2. bzoj 3611: [Heoi2014]大工程 虚树

    题目: 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 ...

  3. bzoj 3611[Heoi2014]大工程 虚树+dp

    题意: 给一棵树 每次选 k 个关键点,然后在它们两两之间 新建 C(k,2)条 新通道. 求: 1.这些新通道的代价和 2.这些新通道中代价最小的是多少 3.这些新通道中代价最大的是多少 分析:较常 ...

  4. bzoj 3611: [Heoi2014]大工程

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...

  5. BZOJ.3611.[HEOI2014]大工程(虚树 树形DP)

    题目链接 要求的和.最大值.最小值好像都可以通过O(n)的树形DP做,总询问点数<=2n. 于是建虚树就可以了.具体DP见DP()函数,维护三个值sum[],mx[],mn[]. sum[]要开 ...

  6. BZOJ 3611 [Heoi2014]大工程 ——虚树

    虚树第二题.... 同BZOJ2286 #include <map> #include <cmath> #include <queue> #include < ...

  7. 3611: [Heoi2014]大工程

    3611: [Heoi2014]大工程 链接 分析: 树形dp+虚树. 首先建立虚树,在虚树上dp. dp:sum[i]为i的子树中所有询问点之间的和.siz[i]为i的子树中有多少询问点,mn[i] ...

  8. BZOJ2286 [Sdoi2011]消耗战 和 BZOJ3611 [Heoi2014]大工程

    2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6371  Solved: 2496[Submit][Statu ...

  9. [Bzoj3611][Heoi2014]大工程(虚树)

    3611: [Heoi2014]大工程 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 2000  Solved: 837[Submit][Status ...

随机推荐

  1. JavaWeb-Servlet-Tomcat

    Servlet就是运行在服务器上的Java类.Servlet容器为javaweb应用提供运行时环境,负责管理Servlet和JSP的生命周期,以及管理它们的共享数据. Servlet容器软件——Tom ...

  2. CS224n学习笔记1——深度自然语言处理

    一.什么是自然语言处理呢? 自然语言处理是计算机科学家提出的名字,本质上与计算机语言学是同义的,它跨越了计算机学.语言学以及人工智能学科. 自然语言处理是人工智能的一个分支,在计算机研究领域中,也有其 ...

  3. Ruby知识点一:方法

    1.实例方法 接收者是对象本身的方法 2.类方法 接收者是类本身的方法,调用类方法时,可以使用::或者.两个符号. 类名.方法名 类名::方法名 3.函数式方法 没有接收者(接收者省略而已)的方法 4 ...

  4. ossec兼容的操作系统

    OSSEC兼容以下操作系统和日志格式 操作系统 以下操作系统可安装OSSEC代理 l  GNU/Linux (all distributions, including RHEL, Ubuntu, Sl ...

  5. 关于java内存泄露的总结--引用的类型:强引用,弱引用,软引用

    今天面试了一家公司的java开发方面的实习生,被问到一个问题:如何处理java中的内存泄露问题,保证java的虚拟机内存不会被爆掉,当时其实觉得面试官的问题有点泛,所以也没有很好领会他的意思,答案也不 ...

  6. exit命令详解

    基础命令学习目录首页 原文链接:https://www.cnblogs.com/itcomputer/p/4157859.html 用途说明 exit命令用于退出当前shell,在shell脚本中可以 ...

  7. Codeforces Round #105 (Div. 2) D. Bag of mice 概率dp

    题目链接: http://codeforces.com/problemset/problem/148/D D. Bag of mice time limit per test2 secondsmemo ...

  8. java 对象和基本数据类型 “==”区别

    “==”比较的是地址,牢记.1.对象.integer 是对象 Integer i1 = 20; Integer i2 = 20 ; System.out.println(i1 == i2); // t ...

  9. 1003 我要通过!| PAT (Basic Level) Practice

    1003 我要通过! (20 分) "答案正确"是自动判题系统给出的最令人欢喜的回复.本题属于 PAT 的"答案正确"大派送 -- 只要读入的字符串满足下列条件 ...

  10. 浏览器播放rtmp流

    我是利用flash插件实现的,需要以下几个文件: flowplayer-3.2.8.min.js flowplayer-3.2.18.swf flowplayer.rtmp-3.2.8.swf flo ...