http://codeforces.com/contest/1341/problem/F
題意:
給出一棵樹,現在要求從點1出發遍歷所有的結點一遍後再回到點1。
操作:
到相鄰點,時間加1
到當前點的之前時間(時光機),但是同一個點同一個時間只能出現一次。
求一個方案使得最大時間最少
解析:
手模最大時間爲最大度。
到達一個點時間爲,到其第一個兒子。返回時其兒子的時間爲,返回點的時間爲。
噹噹前點時間爲時,則變爲(爲了之後返回時爲)
代碼:
/*
* Author : Jk_Chen
* Date : 2020-05-02-22.01.39
*/
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<"> "<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=1e5+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
#define rep_e(i,p,u) for(int i=head[p],u=to[i];i;i=nex[i],u=to[i])
int head[maxn],to[maxn<<1],nex[maxn<<1],now;
void add(int a,int b){
nex[++now]=head[a];head[a]=now;to[now]=b;
}
int deg[maxn];
void init_edge(){
memset(head,0,sizeof head);
now=0;
}
/*_________________________________________________________edge*/
vector<pill>ans;
int mx=-1;
void dfs(int p,int fa,int ti){
int tmp=ti;
ans.pb({p,ti});
int son=deg[p];
if(p!=1)son--;
rep_e(i,p,u){
if(u==fa)continue;
if(ti==mx){
ti-=son+1;
ans.pb({p,ti});
}
dfs(u,p,ti+1);
ti++;
ans.pb({p,ti});
}
if(ti!=tmp-1&&fa)
ans.pb({p,tmp-1});
}
int main(){
int n=rd;
rep(i,1,n-1){
int a=rd,b=rd;
add(a,b);add(b,a);
deg[a]++,deg[b]++;
}
rep(i,1,n)mx=max(mx,deg[i]);
dfs(1,0,0);
printf("%d\n",ans.size());
for(auto P:ans){
printf("%d %d\n",P.fi,P.se);
}
return 0;
}
/*_________________________________________________________end*/