zoukankan      html  css  js  c++  java
  • JZOJ1497 景点中心 题解

    题目:

    数据范围以及样例解释:

    思路

    对于30%的数据,爱怎么做怎么做,我就不信你拿不到。
    对于60%的数据,枚举所有的点作为根,以该点根做dfs可以求出每个点到根的距离dis[i],用每个点的学生人数dis[i]再加起来就是对应的答案,取个最小值即可。枚举O(n),dfs复杂度也是O(n),因此复杂度为O(n^2)。只能通过60%数据。
    对于100%的数据,考虑换根法。即先随意定一点为根(也就是景点中心),并求出其对应答案。我们在60%的做法中,每枚举一个点都对其重新求一遍答案,这样子的效率极其低下,因为我们可以根据已有答案O(1)转移。若已知当前根为u的答案,我们将根变成u的儿子v,那么u的其他儿子的子树中的每个点,都要多走u到v的这段长度,而v的子树中的每个点,都会少走u到v的这段长度。于是我们可以先假设1为根,然后暴力求出其答案,同时求出sum[i]表示以1为根的情况下i的子树中的学生总数。设原来的答案是ret,换成v为根后答案就是ret+(sum[1]-sum[v])
    len[i]-sum[v]*len[i]。
    复杂度就是O(n)
    代码:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    inline int read()
    {
    	int x = 0, f = 0;
    	char c = getchar();
    	for (; c < '0' || c > '9'; c = getchar()) if (c == '-') f = 1;
    	for (; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ '0');
    	return f ? -x : x;
    }
    
    typedef long long ll;
    const int N = 1e5 + 7;
    
    int tot = 0, st[N], to[N << 1], nx[N << 1];
    ll sum[N], a[N], len[N << 1], mi = 0;
    int n, ans;
    
    inline void add(int u, int v, int w) { to[++tot] = v, nx[tot] = st[u], len[tot] = (ll)w, st[u] = tot; }
    void dfs(int u, int from)
    {
    	sum[u] = a[u];
    	for (int i = st[u]; i; i = nx[i]) if (to[i] != from) dfs(to[i], u), sum[u] += sum[to[i]], mi += sum[to[i]] * len[i];
    }
    void getans(int u, int from, ll ret)
    {
    	if (ret < mi) mi = ret, ans = u;
    	for (int i = st[u]; i; i = nx[i])
    		if (to[i] != from)
    			getans(to[i], u, ret - sum[to[i]] * len[i] + (sum[1] - sum[to[i]]) * len[i]);
    }
    
    int main()
    {
    	n = read();
    	for (int i = 1; i <= n; i++) a[i] = (ll)read();
    	for (int i = 1, u, v, w; i < n; i++) u = read(), v = read(), w = read(), add(u, v, w), add(v, u, w);
    	dfs(1, 0);
    	ans = 1;
    	getans(1, 0, mi);
    	printf("%d
    %lld
    ", ans, mi);
    	return 0;
    }
    
  • 相关阅读:
    数组
    Spring创建对象的三种方式以及创建时间
    Struts文件上传下载
    自定义拦截器
    Struts过滤器
    mybatis整合ehcache
    mybatis主键返回
    shell脚本 列出所有网卡的ip地址
    Servlet执行过程
    centos时区
  • 原文地址:https://www.cnblogs.com/zjlcnblogs/p/9277862.html
Copyright © 2011-2022 走看看