zoukankan      html  css  js  c++  java
  • 【POJ3585】Accumulation Degree 二次扫描与换根法

    简单来说,这是一道树形结构上的最大流问题。

    朴素的解法是可以以每个节点为源点,单独进行一次dp,时间复杂度是(O(n^2))
    但是在朴素求解的过程中,相当于每次都求解了一次整棵树的信息,会做了不少的重复工作。
    对于一棵子树的孩子节点和根节点之间存在着最优解的某些关联,因此可以采用自顶向下的一次 dfs 遍历求得结果。

    阶段:子树大小
    状态:当前子树大小的情况下,最大的流量是多少
    状态转移方程:见代码

    代码如下

    #include <cstdio>
    #include <vector>
    #include <memory.h>
    using namespace std;
    const int maxn=2e5+10;
    
    int n,rt,d[maxn],f[maxn],deg[maxn];
    struct node{
    	int to,w;
    	node(int x=0,int y=0):to(x),w(y){}
    };
    vector<node> G[maxn];
    
    #define cls(a,b) memset(a,b,sizeof(a))
    void init(){
    	cls(d,0);cls(f,0);cls(deg,0);
    	for(int i=1;i<=2e5;i++)G[i].clear();
    }
    
    inline void add_edge(int from,int to,int w){
    	G[from].push_back(node(to,w)),++deg[from];
    	G[to].push_back(node(from,w)),++deg[to];
    }
    
    void read_and_parse(){
    	scanf("%d",&n);
    	for(int i=1;i<n;i++){
    		int from,to,w;
    		scanf("%d%d%d",&from,&to,&w);
    		add_edge(from,to,w);
    	}
    }
    
    void dfs1(int u,int fa){
    	for(int i=0;i<G[u].size();i++){
    		int v=G[u][i].to,w=G[u][i].w;
    		if(v==fa)continue;
    		dfs1(v,u);
    		if(deg[v]==1)d[u]+=w;
    		else d[u]+=min(w,d[v]);
    	}
    }
    
    void dfs2(int u,int fa){
    	for(int i=0;i<G[u].size();i++){
    		int v=G[u][i].to,w=G[u][i].w;
    		if(v==fa)continue;
    		if(deg[u]==1)f[v]=d[v]+w;
    		else f[v]=d[v]+min(f[u]-min(w,d[v]),w);
    		dfs2(v,u);
    	}
    }
    
    void solve(){
    	rt=1;
    	dfs1(rt,0);
    	f[rt]=d[rt];//自顶向下需要初始化
    	dfs2(rt,0);
    	
    	int ans=0;
    	for(int i=1;i<=n;i++)ans=max(ans,f[i]);
    	printf("%d
    ",ans);
    }
    
    int main(){
    	int T;scanf("%d",&T);
    	while(T--){
    		init();
    		read_and_parse();
    		solve();
    	}
    	return 0;
    }
    
  • 相关阅读:
    ㊣'undefined' 'object' undefined null
    _#【JS】重复的声明
    _#【JSONP】拒绝访问
    _#href与src的区别
    【OOCSS(stubbornella)】
    【JS兼容】一
    ☀【表单】checkbox
    RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的“添加/删除程序”
    python的缩进问题!
    vim粘贴讲的最好的
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/9871141.html
Copyright © 2011-2022 走看看