zoukankan      html  css  js  c++  java
  • bzoj 2599: [IOI2011]Race

    2599: [IOI2011]Race

    Time Limit: 70 Sec  Memory Limit: 128 MB
    Submit: 4732  Solved: 1385
    [Submit][Status][Discuss]

    Description

    给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, 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

    HINT

     2018.1.3新加数据一组,未重测

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 200010
    #define INF 1000000000
    using namespace std;
    int n,m,num,root,sum,ans;
    int son[maxn],head[maxn],dis[maxn],d[maxn],f[maxn],vis[maxn],t[maxn*5];
    struct node{int to,pre,v;}e[maxn*2];
    void Insert(int from,int to,int v){
        e[++num].to=to;
        e[num].v=v;
        e[num].pre=head[from];
        head[from]=num;
    }
    void getroot(int x,int father){
        son[x]=1;f[x]=0;
        for(int i=head[x];i;i=e[i].pre){
            int to=e[i].to;
            if(to==father||vis[to])continue;
            getroot(to,x);
            son[x]+=son[to];
            f[x]=max(f[x],son[to]);
        }
        f[x]=max(f[x],sum-son[x]);
        if(f[x]<f[root])root=x;
    }
    void cal(int x,int father){
        if(dis[x]<=m)ans=min(ans,d[x]+t[m-dis[x]]);
        for(int i=head[x];i;i=e[i].pre){
            int to=e[i].to;
            if(to==father||vis[to])continue;
            d[to]=d[x]+1;
            dis[to]=dis[x]+e[i].v;
            cal(to,x);
        }
    }
    void add(int x,int father,int flag){
        if(dis[x]<=m){
            if(flag)t[dis[x]]=min(d[x],t[dis[x]]);
            else t[dis[x]]=INF;
        }
        for(int i=head[x];i;i=e[i].pre){
            int to=e[i].to;
            if(to==father||vis[to])continue;
            add(to,x,flag);    
        }
    }
    void solve(int x){
        vis[x]=1;t[0]=0;
        for(int i=head[x];i;i=e[i].pre){
            int to=e[i].to;
            if(vis[to])continue;
            d[to]=1;dis[to]=e[i].v;
            cal(to,0);
            add(to,0,1);
        }
        for(int i=head[x];i;i=e[i].pre){
            int to=e[i].to;
            if(!vis[to])add(to,0,0);
        }
        for(int i=head[x];i;i=e[i].pre){
            int to=e[i].to;
            if(vis[to])continue;
            sum=son[to];root=0;
            getroot(to,0);
            solve(root);
        }
    }
    int main(){
        freopen("Cola.txt","r",stdin);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)t[i]=n;
        int x,y,z;
        for(int i=1;i<n;i++){
            scanf("%d%d%d",&x,&y,&z);
            x++;y++;
            Insert(x,y,z);Insert(y,x,z);
        }
        sum=ans=f[0]=n;
        getroot(1,0);
        solve(root);
        if(ans==n)puts("-1");
        else printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    项目报错二
    项目报错一
    OCP-1Z0-051-V9.02-21题
    Windows API——OpenClipboard——剪切板
    如果在CEdit中实现Ctrl+V、Ctrl+C、Ctrl+X的功能
    OCP-1Z0-051-V9.02-18题
    OCP-1Z0-051-V9.02-17题
    OCP-1Z0-051-V9.02-15题
    OCP-1Z0-051-V9.02-14题
    OCP-1Z0-051-V9.02-12题
  • 原文地址:https://www.cnblogs.com/thmyl/p/8808833.html
Copyright © 2011-2022 走看看