F. Nastya and Time Machine(搜索 构造)

http://codeforces.com/contest/1341/problem/F

题意:

给出一棵树,现在要求从点1出发遍历所有的结点一遍后再回到点1。

操作:
到相邻点,时间加1
到当前点的之前时间(时光机),但是同一个点同一个时间只能出现一次。

求一个方案使得最大时间最少

解析:

手模最大时间为最大度。

到达一个点时间为titi,到其第一个儿子ti+1ti+1。返回时其儿子的时间为titi,返回点的时间为ti+1ti+1

当当前点时间为mxmx时,则变为mxson1mx-son-1(为了之后返回时为ti1ti-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*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章