zoukankan      html  css  js  c++  java
  • AGC103F Distance Sums

    T3 AGC103F

    有n个点的树,边权为1,给出你每个点到其他点的距离和(D_i),构建出这个树.

    (n le 1e5 , D_i le 1e12)

    构造,到其他点距离最大的一定是叶子,若叶子是x,那么fa就是 x + siz[son] - (n - siz[son]) = x - n + 2 * siz[son]

    从下往上构建,即可,最后再检查一遍。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<map>
    using namespace std;
    typedef long long LL;
    const int N = 1e5+10;
    inline LL read()
    {
    	register LL x = 0 , f = 0; register char c = getchar();
    	while(c < '0' || c > '9') f |= c == '-' , c = getchar();
    	while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0' , c = getchar();
    	return f ? -x : x;
    }
    int n;
    LL d[N];
    int eu[N] , ev[N] , siz[N];
    vector<int> G[N];
    map<LL , int> mp;
    struct node
    {
    	LL d;
    	int id;
    }p[N];
    
    inline bool cmp(const node &A , const node &B) { return A.d > B.d; }
    
    void dfs1(int x , int dep , int rot)
    {
    	siz[x] = 1; d[rot] += dep;
    	for(int i = 0 ; i < G[x].size() ; ++i) dfs1(G[x][i] , dep + 1 , rot) , siz[x] += siz[G[x][i]];
    	return ;
    }
    
    void dfs2(int x)
    {
    	for(int i = 0 ; i < G[x].size() ; ++i)
    	{
    		d[G[x][i]] = d[x] + n - 2 * siz[G[x][i]];
    		dfs2(G[x][i]);
    	}
    	return ;
    }
    
    int main()
    {
    	n = read();
    	for(int i = 1 ; i <= n ; ++i) p[i].d = read() , p[i].id = i , mp[p[i].d] = i;
    	LL sum = 0;
    	for(int i = 1 ; i <= n ; ++i) sum += p[i].d;
    	if(sum & 1) { puts("-1"); return 0; }
    	sort(p + 1 , p + 1 + n , cmp);
    	for(int i = 1 ; i <= n ; ++i) siz[i] = 1;
    	for(int i = 1 ; i <  n ; ++i)
    	{
    		LL fa_d = p[i].d - n + 2 * siz[p[i].id];
    		if(!mp.count(fa_d)) { puts("-1"); return 0; }
    		ev[i] = p[i].id; eu[i] = mp[fa_d]; siz[eu[i]] += siz[ev[i]];
    	}
    	for(int i = 1 ; i <  n ; ++i) G[eu[i]].push_back(ev[i]);
    	dfs1(p[n].id , 0 , p[n].id); dfs2(p[n].id);
    	for(int i = 1 ; i <= n ; ++i) if(d[p[i].id] != p[i].d) { puts("-1"); return 0; }
    	for(int i = 1 ; i <  n ; ++i) cout << eu[i] << ' ' << ev[i] << '
    ';
    	return 0;
    }
    
    
  • 相关阅读:
    jQuery学习笔记(一):入门
    jQuery学习笔记(二):this相关问题及选择器
    数据库基础
    有关程序员转行的想法
    在团队中如何带领新手——阅读有感
    C#中的集合类——ArrayList
    .NET基础——ASSCII码表
    C#中的文件操作2
    C#中的文件操作1
    C#中的StringBuilder
  • 原文地址:https://www.cnblogs.com/R-Q-R-Q/p/12996289.html
Copyright © 2011-2022 走看看