zoukankan      html  css  js  c++  java
  • 题解 洛谷 P4189 【[CTSC2010]星际旅行】

    一个比较直接的想法就是对每个点进行拆点,拆成入点和出点,限制放在入点和出点相连的边上,然后跑最大费用最大流即可。

    但是这样复杂度无法接受,所以考虑模拟费用流来解决本题。

    发现 (H) 都大于等于该节点的度数,所以从根节点出发,一定可以到达所有节点。

    先考虑以根节点为起点和终点的答案,首先可以遍历整棵树后回到根节点,每条边的两个端点的 (H) 都减一,答案加二。然后继续考虑每条边的贡献,若其两个端点在遍历后 (H) 不为 (0),则可以反复走这条边,直到其中一个端点的 (H)(0)

    得出根节点的答案后,考虑如何推出其他点的答案。设当前节点为 (x),当前考虑的儿子为 (y)。若 (H_x) 不为 (0),则可以直接从 (x) 走到 (y),使答案加一。若 (H_x)(0),那么从 (y)(x) 后从 (x) 就无法到达 (y),所以进行反悔退流,将原先 (y)(x) 的一个流退掉,如果此时 (y) 存在一个儿子的 (H) 不为 (0),那么其就可以反复走和这个儿子相连的边,使答案加一,若没有,则答案减一。

    同时还要注意在 (dfs) 时需要回溯。

    #include<bits/stdc++.h>
    #define maxn 100010
    using namespace std;
    template<typename T> inline void read(T &x)
    {
        x=0;char c=getchar();bool flag=false;
        while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        if(flag)x=-x;
    }
    int n,tot;
    int v[maxn],ans[maxn],son[maxn];
    struct edge
    {
        int to,nxt;
    }e[maxn];
    int head[maxn],edge_cnt;
    void add(int from,int to)
    {
        e[++edge_cnt]=(edge){to,head[from]};
        head[from]=edge_cnt;
    }
    void dfs_pre(int x,int fa)
    {
        for(int i=head[x];i;i=e[i].nxt)
        {
            int y=e[i].to,val;
            if(y==fa) continue;
            dfs_pre(y,x),val=min(v[x],v[y]);
            v[x]-=val,v[y]-=val,tot+=val*2;
            if(v[y]) son[x]=y;
        }
    }
    void dfs_ans(int x,int fa)
    {
        ans[x]=tot;
        for(int i=head[x];i;i=e[i].nxt)
        {
            int y=e[i].to,type;
            if(y==fa) continue;
            if(v[x]) v[x]--,tot++,type=1;
            else if(son[y]) v[son[y]]--,tot++,type=2;
            else v[y]++,tot--,type=3;
            dfs_ans(y,x);
            if(type==1) v[x]++,tot--;
            if(type==2) v[son[y]]++,tot--;
            if(type==3) v[y]--,tot++;
        }
    }
    int main()
    {
        read(n);
        for(int i=1;i<=n;++i) read(v[i]);
        for(int i=1;i<n;++i)
        {
            int x,y;
            read(x),read(y),x++,y++;
            add(x,y),add(y,x),v[x]--,v[y]--,tot+=2;
        }
        dfs_pre(1,0),dfs_ans(1,0);
        for(int i=1;i<=n;++i) printf("%d
    ",ans[i]);
        return 0;
    }
    
  • 相关阅读:
    jmeter压测,json提取器的使用
    pycharm安装
    安装numpy+mkl
    Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2
    windows上安装tensorflow时报错,“DLL load failed: 找不到指定的模块”的解决方式
    mapreduce 设置递归读取输入文件
    设置reduce Task数量
    kafka.common.FailedToSendMessageException: Failed to send messages after 3 tries.
    mahout RecommenderJob 参数含义
    idea 配置日志输出等级debug
  • 原文地址:https://www.cnblogs.com/lhm-/p/13353381.html
Copyright © 2011-2022 走看看