【CF1340D】 Nastya and Time Machine

题目

题目描述
Denis came to Nastya and discovered that she was not happy to see him… There is only one chance that she can become happy. Denis wants to buy all things that Nastya likes so she will certainly agree to talk to him.

The map of the city where they live has a lot of squares, some of which are connected by roads. There is exactly one way between each pair of squares which does not visit any vertex twice. It turns out that the graph of the city is a tree.

Denis is located at vertex 11 at the time 00 . He wants to visit every vertex at least once and get back as soon as possible.

Denis can walk one road in 11 time. Unfortunately, the city is so large that it will take a very long time to visit all squares. Therefore, Denis took a desperate step. He pulled out his pocket time machine, which he constructed in his basement. With its help, Denis can change the time to any non-negative time, which is less than the current time.

But the time machine has one feature. If the hero finds himself in the same place and at the same time twice, there will be an explosion of universal proportions and Nastya will stay unhappy. Therefore, Denis asks you to find him a route using a time machine that he will get around all squares and will return to the first and at the same time the maximum time in which he visited any square will be minimal.

Formally, Denis’s route can be represented as a sequence of pairs: {v_1, t_1}, {v_2, t_2}, {v_3, t_3}, \ldots, {v_k, t_k}{v
1

,t
1

},{v
2

,t
2

},{v
3

,t
3

},…,{v
k

,t
k

} , where v_iv
i

is number of square, and t_it
i

is time in which the boy is now.

The following conditions must be met:

The route starts on square 11 at time 00 , i.e. v_1 = 1, t_1 = 0v
1

=1,t
1

=0 and ends on the square 11 , i.e. v_k = 1v
k

=1 .
All transitions are divided into two types:
Being in the square change the time: { v_i, t_i } \to { v_{i+1}, t_{i+1} } : v_{i+1} = v_i, 0 \leq t_{i+1} < t_i{v
i

,t
i

}→{v
i+1

,t
i+1

}:v
i+1

=v
i

,0≤t
i+1

<t
i

.
Walk along one of the roads: { v_i, t_i } \to { v_{i+1}, t_{i+1} }{v
i

,t
i

}→{v
i+1

,t
i+1

} . Herewith, v_iv
i

and v_{i+1}v
i+1

are connected by road, and t_{i+1} = t_i + 1t
i+1

=t
i

+1
All pairs { v_i, t_i }{v
i

,t
i

} must be different.
All squares are among v_1, v_2, \ldots, v_kv
1

,v
2

,…,v
k

.
You need to find a route such that the maximum time in any square will be minimal, that is, the route for which \max{(t_1, t_2, \ldots, t_k)}max(t
1

,t
2

,…,t
k

) will be the minimum possible.

输入格式
The first line contains a single integer nn (1 \leq n \leq 10^5)(1≤n≤10
5
) — the number of squares in the city.

The next n - 1n−1 lines contain two integers uu and vv (1 \leq v, u \leq n, u \neq v)(1≤v,u≤n,u


=v) - the numbers of the squares connected by the road.

It is guaranteed that the given graph is a tree.

输出格式
In the first line output the integer kk (1 \leq k \leq 10^6)(1≤k≤10
6
) — the length of the path of Denis.

In the next kk lines output pairs v_i, t_iv
i

,t
i

— pairs that describe Denis’s route (as in the statement).

All route requirements described in the statements must be met.

It is guaranteed that under given restrictions there is at least one route and an answer whose length does not exceed 10^610
6
. If there are several possible answers, print any.

题意翻译
题目大意:给你一棵树,通过每条边需要11的时间,你可以在一个结点处将时间变为任意一个比当前时间小的非负整数,要求满足以下两个限制:

经过每个节点至少一次
每一个节点上,到达它的时间(更改时的时间也计算在内)不得重复
求出任意一种使得到达每个节点的时间最大值最小。

输入输出样例
输入 #1复制
5
1 2
2 3
2 4
4 5
输出 #1复制
13
1 0
2 1
3 2
3 1
2 2
4 3
4 1
5 2
5 1
4 2
2 3
2 0
1 1

思路

首先考虑单纯的走(即不考虑修改时间),每个节点很明显经过的次数是它的度数次,并且,如果考虑修改时间,若修改一次时间不算经过该节点一次的话,那么经过该节点的时间肯定是度数次。
每个点很明显最小是它的度数减一,但是问题在于如果进入这个点时的时间不为00,那么就需要更改一次时间,但是更改时间又会导致当前点时间个数的浪费,所以更改时间自然是越少越好,但因为更改时间不可避免,所以考虑每一个点能否最多只用一次更改时间,这样的话答案就是每个点的度数的最大值。
令maxdeg=maxudegu(degu表示节点u的度数),那么考虑让每一个点的时间取值为[maxdeg−degu,maxdeg],一共有degu+1中取值,满足我们的要求。
接下来就是考虑怎么构造答案了,因为我们钦定每一个节点的时间取值是在一个范围内,所以到儿子的时间就要连续(将该区间看成一个环),因为只能更改一次时间,这可以在当前时间到达maxdeg时更改为maxdeg−degu,然后这题就做完了

代码

#include <cstdio>
using namespace std;
const int Maxn=100000;
int n,ans;
int fa[Maxn+5];
int head[Maxn+5],arrive[Maxn<<1|5],nxt[Maxn<<1|5],tot;
void add_edge(int from,int to){
	arrive[++tot]=to;
	nxt[tot]=head[from];
	head[from]=tot;
}
int deg[Maxn+5];
struct Operation{
	int u,t;
}op[Maxn<<2|5];
int len;
void work_dfs(int u,int t){
	op[++len].u=u;
	op[len].t=t;
	int last=t;
	bool flag=0;
	if(last==ans){
		last=ans-deg[u];
		flag=1;
	}
	for(int i=head[u];i;i=nxt[i]){
		int v=arrive[i];
		if(v==fa[u]){
			continue;
		}
		fa[v]=u;
		if(flag){
			op[++len].u=u;
			op[len].t=last;
			flag=0;
		}
		work_dfs(v,++last);
		op[++len].u=u;
		op[len].t=last;
		if(last==ans){
			last=ans-deg[u];
			flag=1;
		}
	}
	if(flag){
		last=ans;
	}
	if(u!=1&&last!=t-1){
		op[++len].u=u;
		op[len].t=t-1;
	}
}
int main(){
	read(n);
	for(int i=1;i<n;i++){
		int u,v;
		read(u),read(v);
		add_edge(u,v);
		add_edge(v,u);
		deg[u]++,deg[v]++;
	}
	for(int i=1;i<=n;i++){
		ans=max(ans,deg[i]);
	}
	work_dfs(1,0);
	printf("%d\n",len);
	for(int i=1;i<=len;i++){
		printf("%d %d\n",op[i].u,op[i].t);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值