zoukankan      html  css  js  c++  java
  • 题解 luoguP3554 【[POI2013]LUK-Triumphal arch】

    代码的关键部分

    inline void dfs(int u,int fa) {
        int sum=0;
        for(int i=first[u]; i; i=nxt[i]) {
            int v=go[i];
            if(v==fa)continue;
            dfs(v,u);
            sum+=f[v]+1;
        }
      f[u]=max(sum-mid,0);
    
    }

    关于这个方程解释一下

    f[u]=max(sum-mid,0);

    我们不断搜索去边,然后回溯更新每一个阶段需要被染色的数量;

    假设需要被染色的节点数量不足k,即sum-mid<0,那我们取0,原因是每次染色的机会是从后往前推的,即使仍然有染色的机会也不能更新前面的状态;

    而如果需要染色的节点数量大于k,即sum-mid>0,那么我们显然可以累加到父亲节点,在回溯到父亲节点的时候再统一处理,因为在B点在父亲时是可以对儿子节点进行染色的(前提是sum-mid>0,即仍有染色次数),此处区别于上面那种情况;

    所以我们每次二分mid

    如果f[1]=0,显然是合法的,我们就缩小mid

    AC code:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2000005;
    int first[N],nxt[N],go[N],tot,f[N],mid;
    void add(int x,int y) {
        nxt[++tot]=first[x];
        first[x]=tot;
        go[tot]=y;
    }
    inline void dfs(int u,int fa) {
        int sum=0;
        for(int i=first[u]; i; i=nxt[i]) {
            int v=go[i];
            if(v==fa)continue;
            dfs(v,u);
            sum+=f[v]+1;
        }
        f[u]=max(sum-mid,0);
    }
    int main() {
        int n;
        scanf("%d",&n);
        if(n==1)printf("0"),exit(0);
        for(int i=1,x,y; i<n; i++) {
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        int l=1,r=1<<30,ans=0;
        while (l<r) {
            memset(f,0,sizeof(f));
            mid=(l+r)>>1;
            dfs(1,0);
            if (!f[1])r=mid;
            else l=mid+1;
        }
        printf("%d
    ",r);
        return 0;
    }
    View Code
  • 相关阅读:
    Jquery实现类似百度的搜索框
    Spring mvc 初始化过程
    Git学习笔记(2)-Eclipse中Git插件使用
    Git学习笔记(1)
    Tomcat7设置环境变量供java代码读取
    webpack+gulp实现自动构建部署
    netty 粘包问题处理
    java 并发工具类CountDownLatch & CyclicBarrier
    add spring-boot modules to maven project
    Spring Boot (#1 quick start)
  • 原文地址:https://www.cnblogs.com/Larry-Zero/p/11684797.html
Copyright © 2011-2022 走看看