传送门:【BZOJ】2286: [Sdoi2011消耗战

my code:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std ;typedef long long LL ;#define rep( i , a , b ) for ( int i = ( a ) ; i <  ( b ) ; ++ i )
#define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define clrs( a , x , sizes ) memset ( a , x , sizeof ( a[0] ) * ( sizes + 1 ) )
#define clr( a , x ) memset ( a , x , sizeof a )const int MAXN = 250005 ;
const int MAXE = 500005 ;
const int LOG = 20 ;
const int INF = 0x3f3f3f3f ;
const LL oo = 1e18 ;struct Edge {int v , c , n ;Edge () {}Edge ( int v , int c , int n ) : v ( v ) , c ( c ) , n ( n ) {}
} ;Edge preE[MAXE] ;
Edge E[MAXE] ;
int preH[MAXN] , precntE ;
int H[MAXN] , cntE ;
int vis[MAXN] , Time ;
int minv[MAXN][LOG] ;
int S[MAXN] , top ;
int f[MAXN][LOG] ;
int tree[MAXN] ;
int idx[MAXN] ;
int dfs_clock ;
int dep[MAXN] ;
int ask[MAXN] ;
int n , m ;void init () {precntE = 0 ;dfs_clock = 0 ;clrs ( preH , -1 , n ) ;
}void preaddedge ( int u , int v , int c ) {preE[precntE] = Edge ( v , c , preH[u] ) ;preH[u] = precntE ++ ;
}void addedge ( int u , int v , int c ) {if ( vis[u] != Time ) {vis[u] = Time ;H[u] = -1 ;}E[cntE] = Edge ( v , c , H[u] ) ;H[u] = cntE ++ ;
}void dfs ( int u ) {idx[u] = ++ dfs_clock ;for ( int i = preH[u] ; ~i ; i = preE[i].n ) {int v = preE[i].v ;if ( v == f[u][0] ) continue ;dep[v] = dep[u] + 1 ;f[v][0] = u ;minv[v][0] = preE[i].c ;rep ( j , 1 , LOG ) {f[v][j] = f[f[v][j - 1]][j - 1] ;minv[v][j] = min ( minv[v][j - 1] , minv[f[v][j - 1]][j - 1] ) ;}dfs ( v ) ;}
}bool cmp ( const int& x , const int& y ) {return idx[x] < idx[y] ;
}int get_lca ( int x , int y ) {if ( dep[x] < dep[y] ) swap ( x , y ) ;rev ( i , LOG - 1 , 0 ) if ( dep[x] - ( 1 << i ) >= dep[y] ) x = f[x][i] ;if ( x == y ) return x ;rev ( i , LOG - 1 , 0 ) if ( f[x][i] != f[y][i] ) {x = f[x][i] ;y = f[y][i] ;}return f[x][0] ;
}int get_min ( int x , int y ) {int res = INF ;if ( dep[x] < dep[y] ) swap ( x , y ) ;rev ( i , LOG - 1 , 0 ) if ( dep[x] - ( 1 << i ) >= dep[y] ) {res = min ( res , minv[x][i] ) ;x = f[x][i] ;}return res ;
}LL get_ans ( int u , LL dp = 0 ) {for ( int i = H[u] ; ~i ; i = E[i].n ) {if ( ask[E[i].v] == Time ) dp += E[i].c ;else dp += min ( get_ans ( E[i].v ) , ( LL ) E[i].c ) ;}return dp ;
}void deal () {int cnt ;top = 0 ;++ Time ;cntE = 0 ;scanf ( "%d" , &cnt ) ;rep ( i , 0 , cnt ) {scanf ( "%d" , &tree[i] ) ;ask[tree[i]] = Time ;}sort ( tree , tree + cnt , cmp ) ;if ( tree[0] == 1 ) S[++ top] = tree[0] ;else S[++ top] = 1 ;rep ( i , tree[0] == 1 , cnt ) {int t = tree[i] , lca = get_lca ( S[top] , t ) ;while ( top && dep[S[top]] > dep[lca] ) {if ( dep[S[top - 1]] <= dep[lca] ) {int now = S[top --] ;addedge ( lca , now , get_min ( now , lca ) ) ;break ;}addedge ( S[top - 1] , S[top] , get_min ( S[top] , S[top - 1] ) ) ;-- top ;}if ( S[top] != lca ) S[++ top] = lca ;S[++ top] = t ;}while ( top ) {addedge ( S[top - 1] , S[top] , get_min ( S[top] , S[top - 1] ) ) ;-- top ;}LL dp = get_ans ( 1 ) ;printf ( "%lld\n" , dp ) ;
}void solve () {int u , v , c ;init () ;rep ( i , 1 , n ) {scanf ( "%d%d%d" , &u , &v , &c ) ;preaddedge ( u , v , c ) ;preaddedge ( v , u , c ) ;}dfs ( 1 ) ;scanf ( "%d" , &m ) ;rep ( i , 0 , m ) deal () ;
}int main () {Time = 0 ;clr ( vis , 0 ) ;clr ( ask , 0 ) ;while ( ~scanf ( "%d" , &n ) ) solve () ;return 0 ;
}

【BZOJ】2286: [Sdoi2011消耗战【虚树DP】相关推荐

  1. P2495 [SDOI2011]消耗战-虚树+树形dp

    https://www.luogu.com.cn/problem/P2495 虚树:当我们在解决树形dp的问题的时候,题目中会给出一些询问,询问涉及的关键节点不多,并保证总的点数规模的时候,我们就可以 ...

  2. 「Luogu2495」 [SDOI2011]消耗战 虚树

    Luogu P2495 [SDOI2011]消耗战 problem Solution 苦思冥想稍作思考之后可以得到一个树形DP的方法: 令\(w(u,v)\)表示u,v之间的边的权值,\(f[u]\) ...

  3. 洛谷_2495 [SDOI2011]消耗战(虚树)

    消耗战 题目链接:https://www.luogu.com.cn/problem/P2495 题解: 对于单样例,可以考虑树形DP. 但此题是多实例,所以需要对树进行处理,每次询问有k+1(加上一号 ...

  4. 洛谷 P2495 [SDOI2011]消耗战 虚树

    题目描述 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望.已知 ...

  5. P2495 [SDOI2011]消耗战 虚树入门

    一棵树,n个点m个操作.每条边有权值,每个操作给你k个点,问断开若干条边后使k个点与根不相连的最小边权和是多少. 有sigmaK<500000 易知一个裸的树dp需要复杂度,m次操作后总复杂度为 ...

  6. 洛谷P2495 [SDOI2011]消耗战(虚树dp)

    P2495 [SDOI2011]消耗战 题目链接 题解: 虚树\(dp\)入门题吧.虚树的核心思想其实就是每次只保留关键点,因为关键点的dfs序的相对大小顺序和原来的树中结点dfs序的相对大小顺序都是 ...

  7. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问, 每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接. 最少的边权和是多少. (n<=250000,sigma(ki)&l ...

  8. P2495 [SDOI2011]消耗战(树形dp+虚树)

    P2495 [SDOI2011]消耗战 树形dp 状态表示:fuf_ufu​表示以uuu为根的子树中,uuu节点与子树中的关键的"隔开"所需要的最小代价 状态转移: 考虑uuu的一 ...

  9. P2495-[SDOI2011]消耗战【虚树,dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P2495 题目大意 nnn个点的一棵树,mmm次给出一些点,要求割掉最小权值的边使得这些点不和111号点联通. 解题 ...

  10. BZOJ 3611 [Heoi2014]:虚树+树形DP

    时空隧道 今天考试T3正解是虚树-..(看到这个名字我好虚啊-.) 现在我们需要处理一棵树上k个点的询问,做一遍树形DP-- 复杂度是O(n)的,q个询问,感觉复杂度很爆炸-..>_<-- ...

最新文章

  1. Trie(前缀树/字典树)及其应用
  2. Boost:bind绑定和数据成员以及高级用途的测试程序
  3. QT的QGraphicsLinearLayout类的使用
  4. 投票抵制华为鸿蒙系统,网友投票华为十大技术:鸿蒙OS仅排第二!
  5. 看完这些干货帖,大数据产品从入门到精通
  6. LL1分析构造法_【财经职业教育活动周】分析天平的使用——电气环保部
  7. 泰晤士计算机排名2021,THE2021年世界大学专业排名-计算机
  8. EasyTrader踩坑之旅总结
  9. android系统(3)---dumpsys 知识学习
  10. linux 深入检测io详情的工具iopp
  11. I/O端口及其寻址方式
  12. 在 Java 应用程序中定时执行任务
  13. 怎么安装mysql5.6.19_centos6.5 rpm安装mysql5.6.19操作及步骤
  14. 高中计算机考试编程题,高中信息技术《算法及程序设计》试题.docx
  15. Django验证码——手机注册登录
  16. 如何用U盘重新安装Win10系统
  17. Godaddy上的域名如何取消自动续费?
  18. 斯坦福2021秋季·实用机器学习【中文】【合集】+1.1课程介绍
  19. python制作数据增长动图_手把手教你做一个python+matplotlib的炫酷的数据可视化动图...
  20. 华为视频会议终端9039s开机自动入会

热门文章

  1. python中的def是什么意思啊_python的def是什么意思
  2. 论文引用图片时的版权声明(Reproduced with permission, courtesy of [copyright owner])
  3. 一款免费好用的在线高效作图工具
  4. 4G模块Air720系列 android RIL驱动源码发布
  5. python中sorted函数逆序_python中sorted函数
  6. Pandas修改列名
  7. Android-TextView添加字体库
  8. matlab画一只猫,【MATLAB系列04】当一只猫遇见了Matlab
  9. usb口拒绝访问_电脑插上U盘显示无法访问 拒绝访问怎么回事
  10. html横菜单中菜单均匀分布,html – 如何在flexbox中的行间均匀分布元素?