zoukankan      html  css  js  c++  java
  • [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 }
  • 相关阅读:
    改动ScrollView的滑动速度和解决ScrollView与ViewPager的冲突
    SpringMVC 学习笔记(五) 基于RESTful的CRUD
    86/88汇编代码的执行调试
    HTML5+CSS3设计界面
    导入gradle项目
    Gradle安装 Gradle效率提升 eclipse安装gradle插件 【我】
    Eclipse集成Gradle 【Eclipse在线安装Gradle插件方法】
    gradle下载的依赖包位置 及 修改
    idea 普通 web项目配置启动【我】
    理解 IntelliJ IDEA 的项目配置和Web部署
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7597542.html
Copyright © 2011-2022 走看看