zoukankan      html  css  js  c++  java
  • [POI2008]STA-Station

    https://www.luogu.com.cn/problem/P3478
    一道换根DP题。设f[i]为以i为根的答案。先通过一遍dfs,求出f[1]的值。再自上而下进行DP,求出所有儿子节点的值。若节点u的父亲为fa,我们考虑根从fa变为u后,f[fa]怎样得到f[u]。
    再u下方的节点(siz[u])贡献会减去1,在u及其上方(n - siz[u])的贡献会加上1.那么f[u] = f[fa] + n - 2 * siz[u].

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    const int N = 1e6 + 100; 
    typedef long long LL;
    
    LL f[N], dn[N], siz[N];
    int head[N], cnt;
    int n;
    struct Edge {
    	int v, nxt;
    } e[N <<1];
    
    void dfs1(int u, int fa) {
    	siz[u] = 1;
    	for(int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].v;
    		if( v == fa)	continue;
    		dfs1(v, u);
    		dn[u] += dn[v] + siz[v];
    		siz[u] += siz[v];
    	} 
    }
    
    void dfs2(int u, int fa) {
    	if(u == 1)
    		f[u] = dn[u];
    	else f[u] = f[fa] + n - 2 * siz[u];
    	for(int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].v;
    		if( v == fa)	continue;
    		
    		dfs2(v, u); 
    	}
    } 
    
    void AddEdge(int u, int v, int w) {
    	e[++cnt].v = v;
    	e[cnt].nxt = head[u];
    	head[u] = cnt;
    }
    
    int main()
    {
    	scanf("%d", &n);
    	for(int i = 1; i < n; i ++) {
    		int u, v;
    		scanf("%d%d", &u, &v);
    		AddEdge(u, v, 1), AddEdge(v, u, 1);
    	}
    	dfs1(1, 0);
    	dfs2(1, 0);
    	LL ans = 0;
    	int id; 
    	for(int i = 1; i <= n; i ++) {
    		if( f[i] > ans) {
    			ans = f[i];
    			id = i;
    		}
    	}
    	
    	printf("%d
    ", id);
    	return 0;
    }
    
    
  • 相关阅读:
    Docker--使用
    腾讯云发送短信
    Mysql--查询基础
    flask10--数据库链接池(通用),wtforms
    Flask11--Flask-script,sqlalchemy
    序列化 json
    第五章-算术运算符
    计算机网络自顶向下的方法-第二章 应用层
    第三章-数据类型
    第三章-常量和宏定义
  • 原文地址:https://www.cnblogs.com/wyy0804/p/13731778.html
Copyright © 2011-2022 走看看