zoukankan      html  css  js  c++  java
  • ZOJ 3684 Destroy 树的中心

    中心节点就是树的中心,2遍dfs求到树的直径。而中心一定在直径上,顺着直径找到中心就够了。

    然后能够一遍树形DP找到最小值或者二分+推断是否訪问到叶子节点。


    #include <iostream>
    #include<vector>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    struct node
    {
        int next;
        int power;
        int length;
    }t;
    vector<node> tree[10005];
    int st,ed,maxs,n;
    void dfs1(int now,int fa,int sum)
    {
        if(sum>maxs)
        {
            maxs=sum;
            st=now;
        }
        for(int i=0;i<tree[now].size();i++)
        {
            int to=tree[now][i].next;
            int length=tree[now][i].length;
            if(to!=fa)
            {
                dfs1(to,now,sum+length);
            }
        }
    }
    struct node2
    {
        int fa;
        int len;
    }tzf[10005];
    int top,num;
    void dfs2(int now,int fa,int sum)
    {
        if(sum>maxs)
        {
            maxs=sum;
            ed=now;
        }
        for(int i=0;i<tree[now].size();i++)
        {
            int to=tree[now][i].next;
            int length=tree[now][i].length;
            if(to!=fa)
            {
                tzf[to].fa=now;
                tzf[to].len=length;
                dfs2(to,now,sum+length);
            }
        }
    }
    bool cal(int now,int fa,int lim)
    {
        if(tree[now].size()==1)
        {
            return false;
        }
        for(int i=0;i<tree[now].size();i++)
        {
            int to=tree[now][i].next;
            int power=tree[now][i].power;
            if(to!=fa&&power>lim)
            {
                if(!cal(to,now,lim)) return false;
            }
        }
        return true;
    }
    int main()
    {
        int maxx;
        int a,b,c,d;
        while(~scanf("%d",&n))
        {
            maxx=0;
            for(int i=1;i<=n;i++) tree[i].clear();
            for(int i=1;i<n;i++)
            {
                scanf("%d%d%d%d",&a,&b,&c,&d);
                maxx=max(maxx,d);
                t.length=c;;
                t.power=d;
                t.next=b;
                tree[a].push_back(t);
                t.next=a;
                tree[b].push_back(t);
            }
            maxs=0;
            dfs1(1,-1,0);
    
            maxs=0;
            tzf[st].fa=-1;
            dfs2(st,-1,0);
    
            int now=ed,mins=0x3f3f3f3f;
            int zx;
            int sum=0;
    
            while(now!=-1)
            {
                int k=max(sum,maxs-sum);
                if(k<mins)
                {
                    mins=k;
                    zx=now;
                }
                sum+=tzf[now].len;
                now=tzf[now].fa;
            }
            int l=0,r=maxx;
            int ans=0;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(cal(zx,-1,mid))
                {
                    ans=mid;
                    r=mid-1;
                }
                else
                {
                    l=mid+1;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    /*
    7
    1 2 8 2
    1 3 2 2
    3 6 4 0
    2 4 3 0
    2 5 10 0
    5 7 12 0
    
    */


  • 相关阅读:
    Modernizr使用指南(转)
    使用Func<>和Action简化委托
    实现类似MVC ViewBag类型的对象
    更改服务器的SID 加入域控制器提示SID重复
    SQL SERVER 执行大于80M的SQL 脚本
    完全关闭IIS日志,包括System32下的LogFile
    MVC不用302跳转Action,内部跳转
    SHA1l加密
    获取当前时间戳
    invoke反射
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/7132153.html
Copyright © 2011-2022 走看看