bzoj2286 [Sdoi2011]消耗战
来源:互联网 发布:选购笔记本 知乎 编辑:程序博客网 时间:2024/06/06 08:55
bzoj2286 [Sdoi2011]消耗战
Description
在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达。现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望。已知在其他k个岛屿上有丰富能源,为了防止敌军获取能源,我军的任务是炸毁一些桥梁,使得敌军不能到达任何能源丰富的岛屿。由于不同桥梁的材质和结构不同,所以炸毁不同的桥梁有不同的代价,我军希望在满足目标的同时使得总代价最小。
侦查部门还发现,敌军有一台神秘机器。即使我军切断所有能源之后,他们也可以用那台机器。机器产生的效果不仅仅会修复所有我军炸毁的桥梁,而且会重新随机资源分布(但可以保证的是,资源不会分布到1号岛屿上)。不过侦查部门还发现了这台机器只能够使用m次,所以我们只需要把每次任务完成即可。
Input
第一行一个整数n,代表岛屿数量。
接下来n-1行,每行三个整数u,v,w,代表u号岛屿和v号岛屿由一条代价为c的桥梁直接相连,保证1<=u,v<=n且1<=c<=100000。
第n+1行,一个整数m,代表敌方机器能使用的次数。
接下来m行,每行一个整数ki,代表第i次后,有ki个岛屿资源丰富,接下来k个整数h1,h2,…hk,表示资源丰富岛屿的编号。
Output
输出有m行,分别代表每次任务的最小代价。
Sample Input
10
1 5 13
1 9 6
2 1 19
2 4 8
2 3 91
5 6 8
7 5 4
7 8 31
10 7 9
3
2 10 6
4 5 7 8 3
3 9 4 6
Sample Output
12
32
22
【数据规模和约定】
对于10%的数据,2<=n<=10,1<=m<=5,1<=ki<=n-1
对于20%的数据,2<=n<=100,1<=m<=100,1<=ki<=min(10,n-1)
对于40%的数据,2<=n<=1000,m>=1,sigma(ki)<=500000,1<=ki<=min(15,n-1)
对于100%的数据,2<=n<=250000,m>=1,sigma(ki)<=500000,1<=ki<=n-1
虚树裸题
由于想的时候太傻了写了倍增…其实完全不用的…
在网上看到很多人构建虚树时用的是一个比较麻烦的方法?其实按照dfs序排完序求出lca以后再排一遍,依次加到栈里,如果栈顶不是当前点的lca就不断弹出,然后加一条栈顶到当前点的边就好了。
#include <bits/stdc++.h>#define N 500010#define K 20#define INF INT_MAX#define ll long longusing namespace std;int n,m,num,fir[N],nxt[N],to[N],l[N],tot(1),fa[N][K],mn[N][K],h[N],dfn[N],g[N][K],times(0),pos[N];int p[N],p_[N],s[N],top(0),fir_[N],nxt_[N],to_[N],l_[N],tot_(1),l2[N],isp[N];ll f[N];template <class Aqua>inline void read(Aqua &s){ s=0; char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) s=s*10+c-'0',c=getchar();}inline void add(int u,int v,int w){ to[++tot]=v; nxt[tot]=fir[u]; fir[u]=tot; l[tot]=w; to[++tot]=u; nxt[tot]=fir[v]; fir[v]=tot; l[tot]=w;}inline void add_(int u,int v){ to_[++tot_]=v; nxt_[tot_]=fir_[u]; fir_[u]=tot_; to_[++tot_]=u; nxt_[tot_]=fir_[v]; fir_[v]=tot_;}void dfs(int x,int f){ h[x]=h[f]+1; dfn[++times]=x; pos[x]=times; for (int i=fir[x];i;i=nxt[i]) if (to[i]!=f){ fa[to[i]][0]=x,mn[to[i]][0]=l[i]; dfs(to[i],x); dfn[++times]=x; }}inline int Min(int x,int y){ return (h[x]<h[y]?x:y);}void pre(){ dfs(1,0); l2[1]=0; for (int i=2;i<=times;i++) l2[i]=l2[i>>1]+1; for (int i=0;i<=l2[n];i++) mn[0][i]=INF; for (int i=1;i<=l2[n];i++) for (int j=1;j<=n;j++){ fa[j][i]=fa[fa[j][i-1]][i-1]; mn[j][i]=min(mn[j][i-1],mn[fa[j][i-1]][i-1]); } for (int i=1;i<=times;i++) g[i][0]=dfn[i]; for (int i=1;i<=l2[times];i++) for (int j=1;j<=times;j++) g[j][i]=Min(g[j][i-1],g[j+(1<<i-1)][i-1]);}inline bool cmp(int a,int b){ return (pos[a]<pos[b]);}inline int getlca(int a,int b){ a=pos[a],b=pos[b]; if (a>b) swap(a,b); int k=l2[b-a+1]; return Min(g[a][k],g[b-(1<<k)+1][k]);}inline int getlen(int a,int b){ int len=INF; for (int i=l2[h[a]-h[b]];i>=0;i--) if (h[fa[a][i]]>h[b]){ len=min(mn[a][i],len); a=fa[a][i]; } if (a!=b) len=min(len,mn[a][0]); return len;}void dfs_(int x,int Fa){ f[x]=0; for (int i=fir_[x];i;i=nxt_[i]) if (to_[i]!=Fa){ dfs_(to_[i],x); if (isp[to_[i]]) f[x]+=getlen(to_[i],x); else f[x]+=min((ll)getlen(to_[i],x),f[to_[i]]); }}int main(){ read(n); int u,v,w; for (int i=1;i<n;i++){ read(u),read(v),read(w); add(u,v,w); } pre(); read(m); while (m--){ read(num); for (int i=1;i<=num;i++) read(p[i]),p_[i]=p[i],isp[p[i]]=1; sort(p+1,p+1+num,cmp); int num_=num; for (int i=1;i<num_;i++) p[++num]=getlca(p[i],p[i+1]); p[++num]=1; sort(p+1,p+1+num,cmp); num=unique(p+1,p+1+num)-p-1; top=0; for (int i=1;i<=num;i++){ while (top && getlca(s[top],p[i])!=s[top]) top--; if (top) add_(s[top],p[i]); s[++top]=p[i]; } dfs_(1,0); printf("%lld\n",f[1]); for (int i=1;i<=num;i++) fir_[p[i]]=0; tot_=1; for (int i=1;i<=num_;i++) isp[p_[i]]=0; } return 0;}
- bzoj2286: [Sdoi2011]消耗战
- bzoj2286[Sdoi2011消耗战
- [BZOJ2286] [Sdoi2011]消耗战
- [BZOJ2286][SDOI2011]消耗战
- BZOJ2286: [Sdoi2011]消耗战
- bzoj2286: [Sdoi2011消耗战
- bzoj2286【SDOI2011】消耗战
- BZOJ2286: [Sdoi2011]消耗战
- bzoj2286 [Sdoi2011]消耗战
- [BZOJ2286][Sdoi2011消耗战] 虚树
- BZOJ2286: [Sdoi2011]消耗战 虚树
- 【bzoj2286】[Sdoi2011]消耗战
- bzoj2286 [Sdoi2011]消耗战
- 【bzoj2286】【SDOI2011】消耗战
- 【bzoj2286】【sdoi2011】【消耗战】【虚树+dp】
- 【bzoj2286】[Sdoi2011消耗战 虚树+dp
- [虚树dp] bzoj2286: Sdoi2011消耗战
- BZOJ2286: [Sdoi2011]消耗战(虚树)
- 模板——快速幂
- rapidjson中string使用的一点小坑
- Java构建工具, ZeroC ICE, word2vec
- [USACO3.3.1]Riding the Fences
- 浅析设计模式--(一)单例模式
- bzoj2286 [Sdoi2011]消耗战
- 从零开始构建支持TLS1.2的Web服务器Linux版(四)配置FTP环境
- 应届狗的自我修养--unix文件系统学习篇
- 2.使用synchronized关键字实现多线程的同步和互斥(不同线程同时读写同一数据)
- API学习java.lang.Object.getClass
- 【CSS 基础】08 背景
- POJ-1284-Primitive Roots
- 欢迎使用CSDN-markdown编辑器
- Python3.6(3.0以上)安装scrapy