计蒜客42552

计算重心

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 2e5 + 10;
int n;
struct edge {
	int v, next;
}edge[N << 1];
int head[N], cnt;
int sz[N], son[N], par[N], ans[N], anss[N];
int SIZE, rt;
int dp[N];
void addedge(int u, int v) {
	edge[cnt].v = v;
	edge[cnt].next = head[u];
	head[u] = cnt++;
}
void cal(int u, int x) {
	if (x == 0) {
		ans[u] = u; return;
	}
	int mx = INF;
	int rt = x;	
	while (x != par[u]&&max(sz[son[x]],sz[u]-sz[x])<=mx) {
		if (max(sz[son[x]], sz[u] - sz[x]) == mx) {
			anss[u] = x;
		}
		else {
			mx = max(sz[son[x]], sz[u] - sz[x]);
			ans[u] = x;
		}
		x = par[x];
	}
}
void dfs1(int u, int fa) {
	sz[u] = 1;
	par[u] = fa;
	for (int i = head[u]; ~i; i = edge[i].next) {
		int v = edge[i].v;
		if (v == fa)continue;
		dfs1(v, u);
		sz[u] += sz[v];
		if (son[u] == -1 || sz[son[u]] < sz[v])son[u] = v;
	}
}
void dfs2(int u, int fa) {
	for (int i = head[u]; ~i; i = edge[i].next) {
		int v = edge[i].v;
		if (v == fa)continue;
		dfs2(v, u);
	}
	if (son[u] != -1) {
		cal(u, ans[son[u]]);
	}
	else cal(u, 0);
}
int main() {
	n = read();
	memset(head, -1, sizeof(head));
	memset(son, -1, sizeof(son));
	int u, v;
	SIZE = n;
	upd(i, 1, n-1) {
		u = read(), v = read();
		addedge(u, v); addedge(v, u);
	}
	dfs1(1, 0);
	dfs2(1, 0);
	upd(i, 1, n) {
		if (anss[i] && anss[i] < ans[i])swap(anss[i], ans[i]);
		printf("%d", ans[i]);
		if (anss[i])
			printf(" %d\n", anss[i]);
		else puts("");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值