zoukankan      html  css  js  c++  java
  • POJ 3585 Accumulation Degree

    二次扫描与换根法

    用于解决无根树,对于每一个节点作为根时都要统计
    做法:

    1.先以任意一个节点为根,做树形DP,保存每个节点的DP值
    2.然后自上而下dfs,对于每个节点考虑以他为根的最大值

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int MAXN = 200505;
    int init() {
    	int rv = 0, fh = 1;
    	char c = getchar();
    	while(c < '0' || c > '9') {
    		if(c == '-') fh = -1;
    		c = getchar();
    	}
    	while(c >= '0' && c <= '9'){
    		rv = (rv<<1) + (rv<<3) + c -'0';
    		c = getchar();
    	}
    	return fh * rv;
    }
    int T, n, f[MAXN], c[MAXN], degree[MAXN], head[MAXN], nume, rot;
    bool fff[MAXN];
    struct edge{
    	int to, nxt, flow;
    }e[MAXN << 1];
    void adde(int from, int to, int flow) {
    	e[++nume].to = to;
    	e[nume].flow = flow;
    	e[nume].nxt = head[from];
    	head[from] = nume;
    }
    void dfs1(int u) {
    	fff[u] = 1;
    	for(int i = head[u]; i ; i = e[i].nxt) {
    		int v = e[i].to;
    		if(fff[v]) continue;
    		if(degree[v] == 1) {f[u] += e[i].flow;}
    		else {dfs1(v); f[u] += min(f[v], e[i].flow);}
    	}
    }
    void dfs2(int u) {
    	fff[u] = 1;
    	for(int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].to;
    		if(fff[v]) continue;
    		c[v] = f[v];
    		if(degree[u] == 1) c[v] += e[i].flow;
    		else {
    			c[v] += min(c[u] - min(f[u], e[i].flow), e[i].flow);
    		}
    		dfs2(v);
    	}
    }
    int main() {
    	T = init();
    	while(T--) {
    		n = init();
    		memset(fff, 0, sizeof(fff));
    		memset(f, 0, sizeof(f));
    		memset(c, 0, sizeof(c));
    		memset(degree, 0, sizeof(degree));
    		memset(head, 0, sizeof(head));
    		memset(e, 0, sizeof(e));
    		nume = 0;
    		for(int i = 1; i < n; i++) {
    			int u = init(), v = init(), flow = init();
    			adde(u, v, flow); adde(v, u, flow);
    			degree[u]++; degree[v]++;
    		}
    		rot = 1;
    		dfs1(rot);
    		c[rot] = f[rot];
    		memset(fff, 0, sizeof(fff));
    		dfs2(rot);
    		int ans = 0;
    		for(int i = 1;i <= n; i++) ans = max(ans, c[i]);
    		cout << ans << endl;
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    Vmware虚拟机的单用户模式
    Xshell密钥认证
    PuTTY密钥认证
    CentOS 7在NAT模式下配置静态IP
    使用OllyDbg破解EasyCrackMe
    2017 计蒜之道 初赛 第五场 A. UCloud 机房的网络搭建
    2017 计蒜之道 初赛 第五场 A. UCloud 机房的网络搭建
    Kafka常用命令
    选择器和层叠
    语义化
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8610623.html
Copyright © 2011-2022 走看看