zoukankan      html  css  js  c++  java
  • 8VC Venture Cup 2016

    Preorder Test

    题目连接:

    http://www.codeforces.com/contest/627/problem/D

    Description

    For his computer science class, Jacob builds a model tree with sticks and balls containing n nodes in the shape of a tree. Jacob has spent ai minutes building the i-th ball in the tree.

    Jacob's teacher will evaluate his model and grade Jacob based on the effort he has put in. However, she does not have enough time to search his whole tree to determine this; Jacob knows that she will examine the first k nodes in a DFS-order traversal of the tree. She will then assign Jacob a grade equal to the minimum ai she finds among those k nodes.

    Though Jacob does not have enough time to rebuild his model, he can choose the root node that his teacher starts from. Furthermore, he can rearrange the list of neighbors of each node in any order he likes. Help Jacob find the best grade he can get on this assignment.

    A DFS-order traversal is an ordering of the nodes of a rooted tree, built by a recursive DFS-procedure initially called on the root of the tree. When called on a given node v, the procedure does the following:

    Print v.
    Traverse the list of neighbors of the node v in order and iteratively call DFS-procedure on each one. Do not call DFS-procedure on node u if you came to node v directly from u.

    Input

    The first line of the input contains two positive integers, n and k (2 ≤ n ≤ 200 000, 1 ≤ k ≤ n) — the number of balls in Jacob's tree and the number of balls the teacher will inspect.

    The second line contains n integers, ai (1 ≤ ai ≤ 1 000 000), the time Jacob used to build the i-th ball.

    Each of the next n - 1 lines contains two integers ui, vi (1 ≤ ui, vi ≤ n, ui ≠ vi) representing a connection in Jacob's tree between balls ui and vi.

    Output

    Print a single integer — the maximum grade Jacob can get by picking the right root of the tree and rearranging the list of neighbors.

    Sample Input

    5 3
    3 6 1 4 2
    1 2
    2 4
    2 5
    1 3

    Sample Output

    3

    Hint

    题意

    给你一棵树,带点权

    让你找到一个dfs搜索的顺序中,至少大于k个点,且这k个点的最小值最大

    题解:

    二分答案,然后我们进行check

    我们把大于mid的点标为1

    然后我们就可以开始树dp了

    显然对于某个点来说,除了他儿子那棵子树的所有点都是满足条件的,否则他最多选择两个儿子的不完整子树。

    然后我们通过这个进行dp就好了,记录最大值和次大值。

    对了,还得check一下他的父亲,看看这个点是否能够往上延展。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5+7;
    int n,k;
    int a[maxn],w[maxn],sz[maxn],up[maxn],dp[maxn];
    vector<int> E[maxn];
    int flag = 1;
    void dfs(int x,int fa,int m)
    {
        sz[x]=1;
        for(int i=0;i<E[x].size();i++)
        {
            int v = E[x][i];
            if(v==fa)continue;
            dfs(v,x,m);
            w[x]+=w[v];
            sz[x]+=sz[v];
        }
    }
    void solve(int x,int fa,int m)
    {
        int Max1=0,Max2=0,tot=0;
        for(int i=0;i<E[x].size();i++)
        {
            int v=E[x][i];
            if(v==fa)continue;
            if(w[x]-w[v]==sz[x]-sz[v]&&up[x])up[v]=1;
            solve(v,x,m);
            if(a[v]<m)continue;
            if(sz[v]==w[v])tot+=sz[v];
            else
            {
                if(dp[v]>Max1)Max2=Max1,Max1=dp[v];
                else if(dp[v]>Max2)Max2=dp[v];
            }
        }
        if(a[x]<m)return;
        if(tot+Max1+Max2+up[x]*(n-sz[x])+1>=k)flag=1;
        dp[x]=tot+Max1+1;
    }
    int check(int x)
    {
        for(int i=1;i<=n;i++)
            dp[i]=0,up[i]=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]>=x)
                w[i]=1;
            else
                w[i]=0;
        }
        flag = 0;
        dfs(1,-1,x);
        up[1]=w[1];
        solve(1,-1,x);
        return flag;
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<n;i++)
        {
            int x,y;scanf("%d%d",&x,&y);
            E[x].push_back(y);
            E[y].push_back(x);
        }
        int l = 0,r = 1e6+5,ans = 1e6+5;
        while(l<=r)
        {
            int mid = (l+r)/2;
            if(check(mid))l=mid+1,ans=mid;
            else r=mid-1;
        }
        cout<<ans<<endl;
    }
    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    using namespace std;
    int n,m,t,i,x[11][11];
    int mo=10007;
    void multiply(int a[11][11],int b[11][11])
    {
        int i,j,k,c[11][11];
        for (i=0;i<=t;i++)
            for (j=0;j<=t;j++)
            {
                c[i][j]=0;
                for (k=0;k<=t;k++) c[i][j]=(c[i][j]+a[i][k]*b[k][j])%mo;
            }
    
        for (i=0;i<=t;i++)
            for (j=0;j<=t;j++) 
                a[i][j]=c[i][j];
    }
    void binary(int x[11][11],int a)
    {
        int i,j,y[11][11];
        if (a==1) return;
        for (i=0;i<=t;i++)
            for (j=0;j<=t;j++) 
                y[i][j]=x[i][j];
        multiply(x,x);
        binary(x,a/2);
        if (a%2==1) multiply(x,y);
    }
    int main()
    {
        scanf("%d%d%d",&m,&n,&t);
        for (i=0;i<=t;i++)
    	{
            if (i!=0) x[i-1][i]=t-i+1;
            x[i][i]=m-t;
            if (i!=t) x[i+1][i]=i+1;
    	}
    	binary(x,n);
    	printf("%d
    ",x[0][0]);
    }
  • 相关阅读:
    jquery中attr和prop的区别
    director.js:客户端的路由---简明中文教程
    MVC利用Routing实现多域名绑定一个站点、二级域名以及二级域名注册Area
    机器学习——几种分类算法的汇总
    图像预处理(二值化)
    深度学习训练数据打标签过程
    卷积神经网络(CNN)
    机器学习算法中的准确率(Precision)、召回率(Recall)、F值(F-Measure)
    TortoiseGit上传项目到GitHub
    机器学习中的数据清洗与特征工程
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5243112.html
Copyright © 2011-2022 走看看