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

    Description

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

    Input

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

    Output

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

    Code:

    // luogu-judger-enable-o2
    #include<bits/stdc++.h> 
    using namespace std;
    const int maxn=3000000; 
    void setIO(string s)
    {
        string in=s+".in",out=s+".out"; 
        freopen(in.c_str(),"r",stdin); 
        // freopen(out.c_str(),"w",stdout); 
    }
    int root,sn,edges,n,K,tl,tr,ans=1000000000; 
    int f[maxn],siz[maxn],vis[maxn],hd[maxn],to[maxn],nex[maxn],val[maxn],dis1[maxn],dis2[maxn],mine[maxn];   
    void addedge(int u,int v,int c)
    {
        nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c; 
    }
    void getroot(int u,int ff)
    {
        siz[u]=1,f[u]=0; 
        for(int i=hd[u];i;i=nex[i])
        {
            int v=to[i];
            if(v==ff||vis[v]) continue; 
            getroot(v,u); 
            siz[u]+=siz[v];  
            f[u]=max(f[u],siz[v]);            
        } 
        f[u]=max(f[u],sn-siz[u]); 
        if(f[u]<f[root])root=u; 
    }
    void getdis(int u,int ff,int d1,int d2)
    {
        if(d1>K) return; 
        dis1[++tl]=d1,dis2[tl]=d2; 
        for(int i=hd[u];i;i=nex[i])
        {
            int v=to[i];
            if(v==ff||vis[v]) continue; 
            getdis(v,u,d1+val[i],d2+1);  
        }
    }
    void dfs(int u)
    {
        mine[0]=0,tl=0; 
        for(int i=hd[u];i;i=nex[i])
        {
            int v=to[i];
            if(vis[v]) continue; 
            int pdl=tl; 
            getdis(v,u,val[i],1);          
            for(int j=pdl+1;j<=tl;++j) ans=min(ans,mine[K-dis1[j]]+dis2[j]); 
            for(int j=pdl+1;j<=tl;++j) mine[dis1[j]]=min(mine[dis1[j]], dis2[j]); 
        }
        for(int i=1;i<=tl;++i) mine[dis1[i]]=1000000000; 
    }
    void Get(int u)
    {
        vis[u]=1; 
        dfs(u); 
        for(int i=hd[u];i;i=nex[i])
        {
            int v=to[i];
            if(vis[v]) continue; 
            root=0,sn=siz[v]; 
            getroot(v,u); 
            Get(root); 
        }
    }
    int main()
    {
        // setIO("input");
        scanf("%d%d",&n,&K);
        for(int i=1,u,v,c;i<n;++i)
        {
            scanf("%d%d%d",&u,&v,&c),++u,++v; 
            addedge(u,v,c),addedge(v,u,c); 
        }
        for(int i=0;i<maxn;++i) mine[i]=1000000000; 
        vis[0]=1,sn=n,root=0,f[0]=100000000,getroot(1,0),Get(root); 
        printf("%d
    ",ans>=n?-1:ans); 
        return 0; 
    }
    

      

  • 相关阅读:
    Jenkins pipeline基本结构
    接口测试框架httprunner使用自定义extentreports报告模板遇到的问题小结
    python3中扩展字典类实现用点访问属性
    python3系列五可迭代对象、迭代器和生成器
    vue.js-组件嵌套
    使用Vue-CLI3.x进行vue.js环境搭建
    python系列四反射机制
    vue.js环境搭建踩坑记
    python系列三推导式
    python系列二filter()、map()和reduce()
  • 原文地址:https://www.cnblogs.com/guangheli/p/10939790.html
Copyright © 2011-2022 走看看