zoukankan      html  css  js  c++  java
  • CodeForces 1340D Nastya and Time Machine

    CodeForces 1340D Nastya and Time Machine

    https://codeforces.com/contest/1340/problem/D

    (n) 个城市形成了一个树的结构,通过每个道路需要单位 (1) 的时间,Nastya想要从 (1) 节点出发,访问每个节点至少一次后,回到 (1) 节点.

    Nastya有一台时间机器,它可以在一个节点跳回到任意一个过去的时间.但是由于宇宙法则,不能有两个Nastya在同一时间存在与同一城市.

    也就是说,需要找到一个序列 ({u_1,t_1},{u_2,t_2},cdots,{u_k,t_k}) ,满足

    • (u_1=1,t_1=0) , (u_k=1) .
    • (1,2,cdots,n) 均在 (u) 中出现
    • 所有 ({u_i,t_i}) 两两不同

    其中 ((u_i,t_i))((u_{i+1},t_{i+1})) 的关系有两种

    1. Nastya从一个城市走到另一个城市,满足 (u_i,u_{i+1}) 之间有边相连, (t_{i+1}=t_i+1)
    2. Nastya使用了时间机器,满足 (u_i=u_{i+1}) , (0 le t_{i+1} < t_i)

    求一种使得 (max { t_1,t_2,cdots,t_k }) 最小的方案.

    Tutorial

    考虑答案的下界为 (T = max {deg_i }) ,考虑构造.

    我们想要找到一种方案使得到达一个节点 (u) 时,设当前时间为 (t) .每次找到一个未访问的儿子 (v) ,访问子树 (v) ,且满足从子树 (v) 回来时,时间为 (t+1) .分情况讨论

    • (k=deg_v-1) ,如果 (t+k+1 le T) ,那么就可以形如 ((u,t),(v,t+1),(w_1,t+2),cdots,(v,t+k+1),(v,t),(u,t+1))
    • 否则,可以形如 ((u,t),(v,t+1),(w_1,t+2),cdots,(w_{T-t-1},T-1),(v,T),(v,t-(k-(T-t-1))),cdots,(v,t),(u,t+1))

    Code

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #define debug(...) fprintf(stderr,__VA_ARGS__)
    #define fi first
    #define se second
    using namespace std;
    inline char nc()
    {
    //	return getchar();
    	static char buf[100000],*l=buf,*r=buf;
    	return l==r&&(r=(l=buf)+fread(buf,1,100000,stdin),l==r)?EOF:*l++;
    }
    template<class T> void read(T &x)
    {
    	x=0; int f=1,ch=nc();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=nc();}
    	while(ch>='0'&&ch<='9'){x=x*10-'0'+ch;ch=nc();}
    	x*=f;
    }
    typedef pair<int,int> pii;
    const int maxn=1e5+50;
    int n;
    int T;
    int deg[maxn];
    int head[maxn];
    vector<int> adj[maxn];
    vector<pii> an;
    struct edge
    {
    	int to,nex;
    	edge(int to=0,int nex=0):to(to),nex(nex){}
    };
    vector<edge> G;
    inline void addedge(int u,int v)
    {
    	G.push_back(edge(v,head[u])),head[u]=G.size()-1;
    	G.push_back(edge(u,head[v])),head[v]=G.size()-1;
    	++deg[u],++deg[v];
    } 
    void dfs(int u,int t,int fa)
    {
    	an.push_back(make_pair(u,t));
    	for(int i=head[u];~i;i=G[i].nex) 
    	{
    		int v=G[i].to; if(v==fa) continue;
    		adj[u].push_back(v);
    	}
    	int k=adj[u].size();
    	int now=t;
    	for(int i=1;i<=k;++i)
    	{
    		int v=adj[u][i-1];
    		if(now==T)
    		{
    			now=t-1-(k-i+1);
    			an.push_back(make_pair(u,now));
    		}
    		dfs(v,now+1,u);
    		an.push_back(make_pair(u,++now));
    	}
    	if(u!=1&&now!=t-1) an.push_back(make_pair(u,t-1));
    }
    int main()
    {
    	read(n);
    	memset(head,-1,sizeof(head));
    	for(int i=1;i<n;++i)
    	{
    		int u,v; read(u),read(v);
    		addedge(u,v);
    	}
    	T=*max_element(deg+1,deg+n+1);
    	dfs(1,0,0);
    	printf("%d
    ",(int)an.size());
    	for(int i=0;i<an.size();++i)
    	{
    		printf("%d %d
    ",an[i].fi,an[i].se);
    	}
    	return 0;
    }
    
  • 相关阅读:
    005 字符串
    004 变量
    003 python中的内置函数
    002 如何在一台PC上装两个版本的python
    在github上创建新的分支(包括管理分支)
    使用git工具上传自己的程序到github上
    004 Java的一次面试题,学长列举
    为什么分布式一定要有Redis?
    027 ResourceBundle.getBundle方法
    Jenkins下载安装
  • 原文地址:https://www.cnblogs.com/ljzalc1022/p/13191075.html
Copyright © 2011-2022 走看看