bzoj 1808: [Ioi2007]training 训练路径
来源:互联网 发布:软件信息服务业 所得税 编辑:程序博客网 时间:2024/06/17 13:21
题意:在一个图中,有一些边组成了一棵树,其他边都有个权值。你可以删除一些非树边使图中没有长度为偶数的环,问最小代价。
题解:LCA+DP
我们可以把题目转化为选一些边使权值最大。有个结论:最后一定是个仙人掌(一条边最多在一个环里)。那么我们可以状压DP来搞一下。f[i][j]表示已i为根的子树,属于集合j的儿子不考虑的最大权值和。官方题解的图讲的很清晰:
代码:
#include<bits/stdc++.h>using namespace std;int n,m,num=0,fst[1010],nnum=0,sum=0,f[1010][1030],u[2010],sn[1010],vs[1010],nn;struct edge{ int x,y,n;}e[10010];struct nte{ int x,y,c;}ne[5010];vector<int>ee[1010];//每个点是哪些非树边的lcastruct pnt{ int dep,f[12];}p[2010];void ins(int x,int y){ e[++num]={x,y,fst[x]}; fst[x]=num;}void pre(int x,int f){ p[x].f[0]=f; p[x].dep=p[f].dep+1; for(int i=1;i<12;i++) p[x].f[i]=p[p[x].f[i-1]].f[i-1]; for(int i=fst[x];i;i=e[i].n) { int y=e[i].y; if(y==f) continue; u[y]=1<<sn[x]; sn[x]++; pre(y,x); } nn++; vs[x]=nn; u[nn]=0; p[nn].f[0]=x;}int lca(int x,int y){ if(p[x].dep<p[y].dep) swap(x,y); for(int i=11;i>=0;i--) if((1<<i)<=p[x].dep-p[y].dep) x=p[x].f[i]; if(x==y) return x; for(int i=11;i>=0;i--) if(p[x].f[i]!=p[y].f[i]) { x=p[x].f[i]; y=p[y].f[i]; } return p[x].f[0];}void wk(int x){ for(int i=fst[x];i;i=e[i].n) { int y=e[i].y; if(y==p[x].f[0]) continue; wk(y); } for(int i=0;i<ee[x].size();i++) { nte e=ne[ee[x][i]];// printf("%d %d\n",e.x,e.y); int a,b,sum=e.c; for(a=vs[e.x];p[a].f[0]!=x;a=p[a].f[0]) sum+=f[p[a].f[0]][u[a]]; for(b=vs[e.y];p[b].f[0]!=x;b=p[b].f[0]) sum+=f[p[b].f[0]][u[b]]; for(int j=(1<<sn[x])-1;j>=0;j--) { if((j&u[a])==0&&(j&u[b])==0) f[x][j]=max(f[x][j],sum+f[x][j|u[a]|u[b]]); } }}int main(){ scanf("%d%d",&n,&m); nn=n; for(int i=0;i<m;i++) { int x,y,c; scanf("%d%d%d",&x,&y,&c); ne[++nnum]={x,y,c}; sum+=c; if(!c) { ins(x,y); ins(y,x); } } pre(1,0); for(int i=1;i<=nnum;i++) { int hh=lca(ne[i].x,ne[i].y); if(!(p[ne[i].x].dep+p[ne[i].y].dep-(p[hh].dep<<1)&1)||ne[i].c==0) ee[hh].push_back(i); } wk(1);/* for(int i=1;i<=n;i++) { for(int j=0;j<(1<<sn[i]);j++) printf("%d ",f[i][j]); puts(""); }*/ printf("%d",sum-f[1][0]);}
阅读全文
0 0
- bzoj 1808: [Ioi2007]training 训练路径
- 1808: [Ioi2007]training 训练路径|树形DP
- [bzoj1808]/[Ioi2007]training 训练路径
- [IOI2007]Training , [JZOJ5320]偶环
- bzoj 1805: [Ioi2007]Sail 船帆
- bzoj 1804: [Ioi2007]Flood 洪水
- BZOJ 1806 IOI2007 Miners 矿工配餐 动态规划
- bzoj 1806: [Ioi2007]Miners 矿工配餐 动态规划
- Tri-training, 协同训练算法
- Tri-training, 协同训练算法
- USACO training训练题解【1】
- 【bzoj 1806/CS 1801】矿工配餐 IOI2007(五维DP+滚动数组)
- Tri_integral Autumn Training 3 训练总结
- 训练局限玻尔斯曼机(Training Restricted Boltzmann Machines)
- Tri-training regression, 协同训练回归
- 【training】"叉姐的魔法训练"
- Android训练课程(Android Training) - NFC基础
- 协同训练算法之co-training
- 毕业一年多,未来的路该如何走?
- [大数据入门-hadoop基础]eclipse远程调试出现Exception in thread "main" java.lang.UnsatisfiedLinkError
- 事务的传播机制/required 跟 required new 的使用与区别
- React 小贴士
- 大型网站seo技术实施的难点在哪里?
- bzoj 1808: [Ioi2007]training 训练路径
- sublime及notepad++的列块编辑模式
- 变量命名
- 滚动cell 显示隐藏导航栏
- maven入门详解
- spring security源码分析_HttpSessionEventPublisher
- sentry简介--architecture and Components
- DNS智能解析!!
- linux树莓派板子推双流