bzoj 2599: [IOI2011]Race
来源:互联网 发布:python退出程序 exit 编辑:程序博客网 时间:2024/05/21 22:21
Description
给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小.
Input
第一行 两个整数 n, k
第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始)
Output
一个整数 表示最小边数量 如果不存在这样的路径 输出-1
Sample Input
4 3
0 1 1
1 2 2
1 3 4
0 1 1
1 2 2
1 3 4
Sample Output
2
好激动啊我过了IOI的题【虽然是水题】
考虑点分治。对于每棵树记录子节点到根的距离,用vx[x]来存储前面子树的子节点到根的路径中长度为x的最少经历的边数。
然后每次扫一遍更新下ANS就可以了
#include<cstdio>#include<algorithm>using namespace std;struct line{ int s,t; int x; int next;}a[400001];int head[200001];int edge;inline void add(int s,int t,int x){ a[edge].next=head[s]; head[s]=edge; a[edge].s=s; a[edge].t=t; a[edge].x=x;}int mini,minx;int son[200001];bool v[200001];inline void find(int d,int fa,int s){ son[d]=0; int i; int tmp=0; for(i=head[d];i!=0;i=a[i].next) { int t=a[i].t; if(t!=fa&&!v[t]) { find(t,d,s); son[d]+=(son[t]+1); tmp=max(tmp,son[t]+1); } } int mx=max(tmp,s-tmp-1); if(mx<minx||mx==minx&&d<mini) { minx=mx; mini=d; }}struct save{ int x,d; bool operator <(save y)const { return x<y.x; }}sx[200001];int dis[200001],dep[200001];int vx[2000001];int p,k;inline void dfs(int d,int fa){ int i; for(i=head[d];i!=0;i=a[i].next) { int t=a[i].t; if(t!=fa&&!v[t]) { dis[t]=dis[d]+a[i].x; dep[t]=dep[d]+1; p++; sx[p].x=dis[t]; sx[p].d=dep[t]; dfs(t,d); } }}int ans=2100000000;inline void solve(int d){ v[d]=true; int i,j; int l,r; p=0; int p1=0; for(i=head[d];i!=0;i=a[i].next) { int t=a[i].t; if(!v[t]) { dis[t]=a[i].x; dep[t]=1; p++; sx[p].x=dis[t]; sx[p].d=dep[t]; p1=p; dfs(t,d); for(j=p1;j<=p;j++) if(sx[j].x<k) if(vx[k-sx[j].x]!=2100000000) ans=min(vx[k-sx[j].x]+sx[j].d,ans); for(j=p1;j<=p;j++) { if(sx[j].x==k) ans=min(ans,sx[j].d); if(sx[j].x<=k) vx[sx[j].x]=min(vx[sx[j].x],sx[j].d); } } } for(i=1;i<=p;i++) if(sx[i].x<=k) vx[sx[i].x]=2100000000; for(i=head[d];i!=0;i=a[i].next) { int t=a[i].t; if(!v[t]) { mini=0; minx=2100000000; find(t,d,son[t]); int root=mini; solve(root); } }}int main(){//freopen("data.in","r",stdin);//freopen("data.out","w",stdout); int n; scanf("%d%d",&n,&k); int i; int s,t,x; for(i=1;i<=n-1;i++) { scanf("%d%d%d",&s,&t,&x); s++; t++; edge++; add(s,t,x); edge++; add(t,s,x); } mini=0; minx=2100000000; find(1,0,n); int root=mini; for(i=1;i<=2000000;i++) vx[i]=2100000000; solve(root); if(ans==2100000000) printf("-1\n"); else printf("%d\n",ans); return 0;}
0 0
- bzoj 2599: [IOI2011]Race
- bzoj 2599 [IOI2011]Race
- BZOJ 2599: [IOI2011]Race
- BZOJ 2599 [IOI2011]Race【Tree,点分治】
- 【点分治】BZOJ 2599:[IOI2011]Race
- bzoj 2599: [IOI2011]Race (点分治)
- Bzoj 2599: [IOI2011]Race(点分治)
- 点分治[BZOJ]2599: [IOI2011]Race
- 【BZOJ】2599 [IOI2011]Race 点分治
- BZOJ 2599: [IOI2011]Race 点分治题解
- bzoj 2599: [IOI2011]Race 点分治
- 2599: [IOI2011]Race
- BZOJ 2599 IOI2011 Race 树的点分治
- 【BZOJ 2599】 [IOI2011]Race 树的点分治
- bzoj 2599: [IOI2011]Race(树的点分治)
- 【BZOJ】【P2599】【IOI2011】【Race】【题解】【点分治】
- 2599: [IOI2011]Race 点分治
- IOI2011 race
- DevExpress.XtraTreeList.TreeList 显示行号
- Jackson的简单用法
- 关于maxIdle ,MaxActive,maxWait介绍
- Android中adb常用命令
- 更大权限,以管理员身份运行msi安装包
- bzoj 2599: [IOI2011]Race
- Android点滴---drawable粘贴图片后 R文件报错,解决
- [android] 最新的版本分布,分辨率分布在哪里查看
- 使用md5对数据进行加密
- Hibernate主键生成策略
- VLC SDK在VS2010中的配置及简单使用举例
- 先回调,在上冲,非农前夕不平静--4月2
- javascript中的面向对象设计案例
- ArrayList与LinkedList的区别