[IOI 2011]Race

Description

给一棵树,每条边有非负权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, 1 <= K <= 1000000

Input

第一行 两个整数 n, k

第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始)

Output

一个整数 表示最小边数量 如果不存在这样的路径 输出-1

Sample Input

4 3

0 1 1

1 2 2

1 3 4

Sample Output

2

转载自Navi_Awson的博客:http://www.cnblogs.com/NaVi-Awson/p/7560921.html

%%%Navi_Gayson大佬

有这个链接就行了,懒得写题解zyys

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 struct Node
  7 {
  8   int next,to,dis;
  9 }edge[400001];
 10 int num,head[200001],f[1000001],ans,k;
 11 int size[200001],maxsize[200001],minsize,root,n;
 12 bool vis[200001];
 13 int gi()
 14 {
 15   char ch=getchar();
 16   int x=0;
 17   while (ch<‘0‘||ch>‘9‘) ch=getchar();
 18   while (ch>=‘0‘&&ch<=‘9‘)
 19     {
 20       x=x*10+ch-‘0‘;
 21       ch=getchar();
 22     }
 23   return x;
 24 }
 25 void add(int u,int v,int dis)
 26 {
 27   num++;
 28   edge[num].next=head[u];
 29   head[u]=num;
 30   edge[num].to=v;
 31   edge[num].dis=dis;
 32 }
 33 void get_size(int x,int fa)
 34 {int i;
 35   size[x]=1;
 36   maxsize[x]=0;
 37   for (i=head[x];i;i=edge[i].next)
 38     {
 39       int v=edge[i].to;
 40       if (vis[v]==0&&v!=fa)
 41     {
 42       get_size(v,x);
 43       size[x]+=size[v];
 44       maxsize[x]=max(maxsize[x],size[v]);
 45     }
 46     }
 47 }
 48 void get_root(int r,int x,int fa)
 49 {int i;
 50   maxsize[x]=max(maxsize[x],size[r]-size[x]);
 51   if (maxsize[x]<minsize)
 52     {root=x;minsize=maxsize[x];}
 53   for (i=head[x];i;i=edge[i].next)
 54     {
 55       int v=edge[i].to;
 56       if (vis[v]==0&&v!=fa)
 57     {
 58       get_root(r,v,x);
 59     }
 60     }
 61 }
 62 void get_ans(int x,int fa,int cnt,int val)
 63 {int i;
 64   if (val>k) return;
 65   if (f[k-val]||k==val)
 66   ans=min(ans,f[k-val]+cnt);
 67   for (i=head[x];i;i=edge[i].next)
 68     {
 69       int v=edge[i].to;
 70       if (vis[v]==0&&v!=fa)
 71     {
 72       get_ans(v,x,cnt+1,val+edge[i].dis);
 73     }
 74     }
 75 }
 76 void get_update(int x,int fa,int cnt,int val)
 77 {int i;
 78   if (val>k) return;
 79   if (f[k]==0) f[k]=cnt;
 80   else f[k]=min(f[k],cnt);
 81   for (i=head[x];i;i=edge[i].next)
 82     {
 83       int v=edge[i].to;
 84       if (vis[v]==0&&v!=fa)
 85     {
 86       get_update(v,x,cnt+1,val+edge[i].dis);
 87     }
 88     }
 89 }
 90 void get_delete(int x,int fa,int cnt,int val)
 91 {int i;
 92   if (val>k) return;
 93   f[val]=0;
 94   for (i=head[x];i;i=edge[i].next)
 95     {
 96       int v=edge[i].to;
 97       if (vis[v]==0&&v!=fa)
 98     {
 99       get_delete(v,x,cnt+1,val+edge[i].dis);
100     }
101     }
102 }
103 void solve(int x)
104 {int i;
105    minsize=2e9;
106    get_size(x,0);
107    get_root(x,x,0);
108    vis[root]=1;
109    for (i=head[root];i;i=edge[i].next)
110      {
111        int v=edge[i].to;
112        if (vis[v]==0)
113      {
114        get_ans(v,root,1,0);
115        get_update(v,root,1,0);
116      }
117      }
118    for (i=head[root];i;i=edge[i].next)
119      {
120        int v=edge[i].to;
121        if (vis[v]==0)
122      {
123        get_delete(v,root,1,0);
124      }
125      }
126    for (i=head[root];i;i=edge[i].next)
127      {
128        int v=edge[i].to;
129        if (vis[v]==0)
130      {
131        solve(v);
132      }
133      }
134 }
135 int main()
136 {int i,u,v,w;
137   cin>>n>>k;
138   for (i=1;i<=n-1;i++)
139     {
140       u=gi();v=gi();w=gi();
141       u++;v++;
142       add(u,v,w);
143       add(v,u,w);
144     }
145   ans=2e9;
146   solve(1);
147   if (ans==2e9) cout<<-1;
148   else cout<<ans;
149 }
时间: 2024-08-05 22:09:44

[IOI 2011]Race的相关文章

BZOJ 2600 IOI 2011 ricehub 二分

题目大意:给出粮食的位置,给出初始的钱数,问粮仓设在哪里会让收到的粮食最多.粮食运到粮仓需要花费|x - x'|的费用. 思路:看到L和B的范围都大的惊人,只能从R来下手.能不能从每个粮食的位置入手来搞点什么. 首先要想收购的尽量多,收购的粮食应该是一段连续的区间.对于每个粮食的位置,以这个粮食的位置为起点所能够收购到的粮食是单调的.这个就可以二分来确定了.一段区间内到达所有点最近的点是中位数,所以就可以O(1)判断了. (这真的是IOI题么.. CODE: #include <cstdio>

IOI 2011 Rice Hub 米仓

题目 分析 首先来观察一下这题的数据范围,Subtask 4当中的数据量10^15大到惊人的程度.很显然这是我们所不能够处理的数据量.但转而看R的大小,就令人能够接受了,那么不难想到,这里有一个离散化的思路. 然后我们考虑如何安排这个米仓.这个米仓其实就相当于一个"中位数",也就是安排在米仓能够处理的区间的正当中. 这里出现了一个"区间"的概念,那么我们就可以想到用一个类似二分的思想来枚举区间的左右边界. 首先O(R)枚举左边界,然后嵌一个while查右边界,写一个

【BZOJ-2599】Race 点分治

2599: [IOI2011]Race Time Limit: 70 Sec  Memory Limit: 128 MBSubmit: 2590  Solved: 769[Submit][Status][Discuss] Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始) Output

hdu 4123 Bob’s Race 树的直径+rmq+尺取

Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble in choosing the route. There are N houses and N - 1 roads

HDOJ 题目4123 Bob’s Race(树的直径+RMQ优化)

Bob's Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2753    Accepted Submission(s): 888 Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble

USACO Section 4.3 Street Race(图的连通性+枚举)

虽说是IOI'95,但是也是挺水的..for 第一问,n最大为50,所以可以直接枚举起点和终点之外的所有点,然后dfs判断是否连通:for 第二问,易知答案一定是第一问的子集,所以从第一问中的答案中枚举,也是用dfs判断. #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<vector> #define rep(i,r) for(i

hdu 4123 Bob’s Race (树的直径相关+rmq+单调队列思想)

Bob's Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2115    Accepted Submission(s): 658 Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble

BZOJ2440 [中山市选2011]完全平方数

Description 小 X 自幼就很喜欢数.但奇怪的是,他十分讨厌完全平方数.他觉得这些数看起来很令人难受.由此,他也讨厌所有是完全平方数的正整数倍的数.然而这丝毫不影响他对其他数的热爱. 这天是小X的生日,小 W 想送一个数给他作为生日礼物.当然他不能送一个小X讨厌的数.他列出了所有小X不讨厌的数,然后选取了第 K个数送给了小X.小X很开心地收下了. 然而现在小 W 却记不起送给小X的是哪个数了.你能帮他一下吗? Input 包含多组测试数据.文件第一行有一个整数 T,表示测试数据的组数.

开始使用CCA CRM 2011

你可能从微软的市场动态获知我们最近发布了最新版本的Microsoft Dynamics CRM 2011的客户关怀加速器(CCA R2).CCA在一个单一的用户界面提供呼叫中心功能相结合的,能够显示和操纵来自不同业务应用程序的数据.CCA提供了许多功能,包括: l 集成代理的桌面 l 脚本以消除重复的数据输入 l 计算机电话集成(CTI) l 代理活动报告 CCA的核心是一个允许开发人员构建自己的代理的桌面,并提供多会话管理等功能的框架.UI集成不同类型的应用程序(包括Web.Windows窗体