zoukankan      html  css  js  c++  java
  • 51NOD 1424 零树

    Discription

    有一棵以1为根的树,他有n个结点,用1到n编号。第i号点有一个值vi。

    现在可以对树进行如下操作:

    步骤1:在树中选一个连通块,这个连通块必须包含1这个结点。

    步骤2:然后对这个连通块中所有结点的值加1或者减1。

    问最少要经过几次操作才能把树中所有结点都变成0。

    注意:步骤1与步骤2合在一起为一次操作。


    Input

    单组测试数据。 
    第一行有一个整数n(1 ≤ n ≤ 10^5) 
    接下来n-1行,每行给出 ai 和 bi (1 ≤ ai, bi ≤ n; ai ≠ bi),表示ai和bi之间有一条边,输入保证是一棵树。 
    最后一行有n个以空格分开的整数,表示n个结点的值v1, v2, ..., vn (|vi| ≤ 10^9)。

    Output

    输出一个整数表示最少的操作步数。

    Sample Input

    3
    1 2
    1 3
    1 -1 1

    Sample Output

    3


    题解见注释(真的不知道我怎么想到差分约束的2333,网上全是用树上dp做的。。。)
    /*
        考虑差分约束。
    	1.设每个点i被add(i)次加操作涉及到,被dec(i)次减操作涉及到, 那么:
    	    add(i) - dec(i) + w[i] = 0.
    	2.把dec用add表示后,每个点有两个限制:
    	    (1). add(i) >= max{0,-w[i]}
    	    (2). add(i) <= add(fa) + min{0,w[fa]-w[i]} 
    	
    	然后直接跑一个最短路,2*add(1) + w[1] 就是答案. 
    */
    #include<bits/stdc++.h>
    #define ll long long
    #define pb push_back
    using namespace std;
    const int maxn=100005;
    vector<int> g[maxn];
    int ne[maxn*5],to[maxn*5],num;
    int hd[maxn],val[maxn*5],n,m,w[maxn];
    bool iq[maxn];
    ll d[maxn];
    
    inline void add(int x,int y,int z){
    	to[++num]=y,ne[num]=hd[x],hd[x]=num,val[num]=z;
    }
    
    void dfs(int x,int fa){
    	add(fa,x,min(0,w[fa]-w[x]));
    	for(int i=g[x].size()-1,TO;i>=0;i--){
    		TO=g[x][i];
    		if(TO==fa) continue;
    		dfs(TO,x);
    	}
    }
    
    inline void build(){
    	for(int i=1;i<=n;i++) add(i,0,min(0,w[i]));
    	dfs(1,1);
    }
    
    inline void spfa(){
    	queue<int> q;
    	for(int i=0;i<=n;i++) q.push(i),iq[i]=1;
    	int x;
    	while(!q.empty()){
    		x=q.front(),q.pop();
    		for(int i=hd[x];i;i=ne[i]) if(d[x]+(ll)val[i]<d[to[i]]){
    			d[to[i]]=d[x]+(ll)val[i];
    			if(!iq[to[i]]) q.push(to[i]),iq[to[i]]=1;
    		}
    		iq[x]=0;
    	}
    	for(int i=1;i<=n;i++) d[i]-=d[0];
    }
    
    int main(){
    	scanf("%d",&n);
    	int uu,vv;
    	for(int i=1;i<n;i++){
    		scanf("%d%d",&uu,&vv);
    		g[uu].pb(vv),g[vv].pb(uu);
    	}
    	for(int i=1;i<=n;i++) scanf("%d",w+i);
    	
    	build();
    	spfa();
    	
    	printf("%lld
    ",d[1]*2+(ll)w[1]);
    
    	return 0;
    }
    

      

     
  • 相关阅读:
    django静态资源转移
    QT5 内置Multimedia开发音乐播放器
    Qt Creator 设置编码格式为 UTF-8
    QT 出错 moc_mainwindow.obj:-1: error: LNK2019: 无法解析的外部符号 " 中被引用...
    linux 安装node, 添加软链接,更改npm安装源
    django.template.exceptions.TemplateDoesNotExist: index.html
    centos下使用virtualenv建立python虚拟环境
    win7上 nginx 出现 403 Forbidden
    django安装xadmin中出现的报错汇总
    centos安装mysql57
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8807625.html
Copyright © 2011-2022 走看看