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

    2599: [IOI2011]Race

    Time Limit: 70 Sec  Memory Limit: 128 MB
    Submit: 4559  Solved: 1343
    [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新加数据一组,未重测

    分析:复习了一下点分治. 这道题在点分治模板的基础上改改就好了. dfs到一个点添加重心到它的距离和经过的边数,最后两个指针扫一下就好了.

    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 300010;
    int n,k,head[maxn],to[maxn * 2],nextt[maxn * 2],w[maxn * 2],tot = 1,d[maxn],num[maxn];
    int sizee[maxn],f[maxn],sum,root,vis[maxn],ans[1000010],anss = -1,top;
    
    struct node
    {
        int p1,p2;
    }e[maxn];
    
    void add(int x,int y,int z)
    {
        w[tot] = z;
        to[tot] = y;
        nextt[tot] = head[x];
        head[x] = tot++;
    }
    
    void findroot(int u,int fa)
    {
        sizee[u] = 1;
        f[u] = 0;
        for (int i = head[u]; i; i = nextt[i])
        {
            int v = to[i];
            if (vis[v] || v == fa)
                continue;
            findroot(v,u);
            sizee[u] += sizee[v];
            f[u] = max(f[u],sizee[v]);
        }
        f[u] = max(f[u],sum - sizee[u]);
        if (f[u] < f[root])
            root = u;
    }
    
    void dfs1(int u,int d1,int d2,int fa)
    {
        d[u] = d1;
        num[u] = d2;
        for (int i = head[u];i;i = nextt[i])
        {
            int v = to[i];
            if (vis[v] || v == fa)
                continue;
            dfs1(v,d1 + w[i],d2 + 1,u);
        }
    }
    
    void dfs2(int u,int fa)
    {
        e[++top].p1 = d[u];
        e[top].p2 = num[u];
        for (int i = head[u];i;i = nextt[i])
        {
            int v = to[i];
            if (vis[v] || v == fa)
                continue;
            dfs2(v,u);
        }
    }
    
    bool cmp(node a,node b)
    {
        if (a.p1 == b.p1)
            return a.p2 < b.p2;
        return a.p1 < b.p1;
    }
    
    void calc1(int u,int W)
    {
        top = 0;
        dfs2(u,0);
        sort(e + 1,e + 1 + top,cmp);
        int l = 1,r = top;
        while (l <= r)
        {
            while (l < r && e[l].p1 + e[r].p1 > k)
                r--;
            for (int kk = r; e[l].p1 + e[kk].p1 == k; kk--)  //这里不是直接移动r.
                ans[e[kk].p2 + e[l].p2]++;
            l++;
        }
    }
    
    void calc2(int u,int W)
    {
        top = 0;
        dfs2(u,0);
        sort(e + 1,e + 1 + top,cmp);
        int l = 1,r = top;
        while (l <= r)
        {
            while (l < r && e[l].p1 + e[r].p1 > k)
                r--;
            for (int kk = r; e[l].p1 + e[kk].p1 == k; kk--)
                ans[e[kk].p2 + e[l].p2]--;
            l++;
        }
    }
    
    void solve(int u)
    {
        vis[u] = 1;
        dfs1(u,0,0,0);
        calc1(u,0);
        for (int i = head[u]; i; i = nextt[i])
        {
            int v = to[i];
            if (vis[v])
                continue;
            calc2(v,w[i]);
            f[0] = sum = sizee[v];
            findroot(v,root = 0);
            solve(root);
        }
    }
    
    int main()
    {
        scanf("%d%d",&n,&k);
        for (int i = 1; i < n; i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            x++;
            y++;
            add(x,y,z);
            add(y,x,z);
        }
        f[0] = sum = n;
        findroot(1,0);
        solve(root);
        for (int i = 1; i <= n; i++)
            if (ans[i])
            {
                anss = i;
                break;
            }
        printf("%d
    ",anss);
    
        return 0;
    }
  • 相关阅读:
    test
    【转载】ASP.NET MVC 3 —— Model远程验证
    【转载】富有客户端技术之——jQuery EasyUI
    【转载】基于ASP.NET Web Application的插件实现,附DEMO
    【转载】浅谈C#中的延迟加载(1)——善用委托
    【转载】Winform开发框架之权限管理系统
    【转载】基于我的Winform开发框架扩展而成的WCF开发框架
    [转载]10大优秀的移动Web应用程序开发框架推荐
    [转载]C#泛型列表List<T>基本用法总结
    [转载]推荐一个被大家忽视的微软的反跨站脚本库AntiXSS V3.1
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8509167.html
Copyright © 2011-2022 走看看