详细做法以及证明请看论文《Hamiltonian paths in the square of a tree》

首先将1到n的路径提取出来,作为主干。

定义毛毛虫为去掉叶子之后只有一条单链的树,定义non-trivial的毛毛虫为单链非空的毛毛虫。

对于主干上每个点,计算它的非主干部分是否是毛毛虫,如果某个部分不是毛毛虫,那么肯定无解。

将主干上每个点划分为两类:

A:non-trivial的毛毛虫不超过1个。

B:non-trivial的毛毛虫恰有两个。

同时定义一个点是free的当且仅当它是单点。

如下图:

判断一下是否每对相邻的B类点中间都有free点,且所有B类点前后都有free点,如果没有,那么也无解。

现在必然存在一条以1为起点,且依次遍历完主干上每个点及其子树的2H-哈密顿路径。

对于1,如果它是free的,那么方案显然,否则从1出去的点必定是它子树里离它距离只有1的点。

然后一个一个构造,如果上一个点是第二层的点,那么这一部分起点必须为主干上的点,否则起点选第二层的点显然更优。

对于一个毛毛虫,可以直接构造出2H-哈密顿环,从中断开某条路径得到合法的方案。

如下图:

但是如果一个点是B类点,这个时候是不能如此构造的,只能是起点和终点都是第二层的点,而且起点优先考虑叶子节点,这个时候就又可以按之前的方法构造。

最后再检验一下终点是否为n即可,时间复杂度$O(n)$。

#include<cstdio>
#include<cstdlib>
#define N 500010
int n,i,j,x,y,S,T,d[N],g[N],v[N<<1],nxt[N<<1],ed,pre[N],sub[N];
int f[N],G[N],V[N],NXT[N];
int m,a[N],ans,fin[N],cnt,q[N],b[N<<1],tot;bool vip[N],fr[N];
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
void NO(){puts("BRAK");std::exit(0);}
inline void swap(int&a,int&b){int c=a;a=b;b=c;}
inline void reserve(int*a,int n){for(int i=1,j=n;i<j;i++,j--)swap(a[i],a[j]);}
inline void add(int x,int y){d[x]++;v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
inline void ADD(int x,int y){f[y]=x;V[++ed]=y;NXT[ed]=G[x];G[x]=ed;}
void dfs(int x,int y){
pre[x]=y;
for(int i=g[x];i;i=nxt[i])if(v[i]!=y)dfs(v[i],x);
}
bool spine(int x,int y){
int t=0;
for(int i=g[x];i;i=nxt[i])if(v[i]!=y&&d[v[i]]>1){
if(!spine(v[i],x))return 0;
if(t++)return 0;
}
return 1;
}
inline int any_secondary_node(int x){
for(int i=g[x];i;i=nxt[i])if(!vip[v[i]])return v[i];
}
inline int a_secondary_node_preferably_leaf(int x){
for(int i=g[x];i;i=nxt[i])if(!vip[v[i]]&&d[v[i]]==1)return v[i];
return any_secondary_node(x);
}
inline int another_secondary_node(int x,int y){
for(int i=g[x];i;i=nxt[i])if(!vip[v[i]]&&v[i]!=y)return v[i];
}
void findspine(int x,int y){
q[++cnt]=x;
for(int i=g[x];i;i=nxt[i])if(v[i]!=y)if(d[v[i]]==1)ADD(x,v[i]);else findspine(v[i],x);
}
inline int left(int x){return x==1?tot:x-1;}
inline int right(int x){return x==tot?1:x+1;}
inline void extend(int x,int a=0,int b=0){
for(int i=G[x];i;i=NXT[i])if(V[i]!=a&&V[i]!=b)fin[++ans]=V[i];
}
inline void path_caterpillar(int x,int S,int T){
fin[++ans]=S;
if(S==T)return;
int i,j,A,B;
q[cnt=1]=x;
for(i=g[x];i;i=nxt[i])if(!vip[v[i]]){
if(d[v[i]]==1)ADD(x,v[i]);
else{
if(cnt>1)reserve(q,cnt);
findspine(v[i],x);
}
}
for(i=1;i<=cnt;i++){
b[i]=i&1?q[i]:-q[i];
b[cnt+cnt-i+1]=-b[i];
}
for(tot=0,i=1;i<=cnt+cnt;i++){
if(b[i]<0)if(!G[-b[i]])continue;
b[++tot]=b[i];
}
if(d[S]>1)A=S;else A=-f[S];
if(d[T]>1)B=T;else B=-f[T];
for(i=1;i<=tot;i++)if(b[i]==A)break;
if(A<0)extend(-A,S,T);
if(b[left(i)]==B)
for(j=right(i);b[j]!=B;j=right(j))if(b[j]>0)fin[++ans]=b[j];else extend(-b[j]);
else
for(j=left(i);b[j]!=B;j=left(j))if(b[j]>0)fin[++ans]=b[j];else extend(-b[j]);
if(B<0&&A!=B)extend(-B,S,T);
fin[++ans]=T;
}
int main(){
read(n);
for(i=1;i<n;i++)read(x),read(y),add(x,y),add(y,x);
dfs(n,ed=0);
for(i=1;i!=n;i=pre[i])a[++m]=i;a[++m]=i;
for(i=1;i<=m;i++)vip[a[i]]=1;
for(i=1;i<=m;i++){
x=a[i];fr[x]=1;
for(j=g[x];j;j=nxt[j]){
y=v[j];
if(vip[y])continue;
fr[x]=0;
if(d[y]==1)continue;
sub[x]++;
if(sub[x]>2)NO();
if(!spine(y,x))NO();
}
}
for(i=1,j=0;i<=m;i++){
x=a[i];
if(fr[x])j=1;
else if(sub[x]==2){
if(j!=1)NO();
j=2;
}
}
if(j==2)NO();
S=a[1];
if(fr[a[1]])T=a[1];else T=any_secondary_node(a[1]);
path_caterpillar(a[1],S,T);
for(i=2;i<=m;i++){
x=a[i];
if(fr[x])S=T=x;
else if(!vip[T]){
S=x;
T=a_secondary_node_preferably_leaf(x);
}else{
S=a_secondary_node_preferably_leaf(x);
T=sub[x]<2?x:another_secondary_node(x,S);
}
path_caterpillar(x,S,T);
}
if(fin[n]!=n)NO();
for(i=1;i<=n;i++)printf("%d\n",fin[i]);
return 0;
}

  

BZOJ3424 : Poi2013 Multidrink的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. [POI2013]Łuk triumfalny

    [POI2013]Łuk triumfalny 题目大意: 一棵\(n(n\le3\times10^5)\)个结点的树,一开始\(1\)号结点为黑色.\(A\)与\(B\)进行游戏,每次\(B\)能选 ...

  3. [POI2013]Polaryzacja

    [POI2013]Polaryzacja 题目大意: 给定一棵\(n(n\le250000)\)个点的树,可以对每条边定向成一个有向图,这张有向图的可达点对数为树上有路径从\(u\)到达\(v\)的点 ...

  4. [POI2013]Taksówki

    [POI2013]Taksówki 题目大意: ABC三地在同一条直线上,AC相距\(m(m\le10^{18})\)米,AB相距\(d\),B在AC之间.总共有\(n(n\le5\times10^5 ...

  5. [POI2013]Usuwanka

    [POI2013]Usuwanka 题目大意: 一排\(n\)个球,有黑白两种颜色.每取走一个球会在原位置放一个水晶球.求构造一种取球方案,满足: 每次取走\(k\)个白球和\(1\)个黑球: 一次取 ...

  6. [POI2013]Morskie opowieści

    [POI2013]Morskie opowieści 题目大意: 一个\(n(n\le5000)\)点\(m(m\le5000)\)边无向图,边权均为\(1\),有\(k(k\le10^6)\)个询问 ...

  7. [POI2013]Bajtokomputer

    [POI2013]Bajtokomputer 题目大意: 给定一个长度为\(n(n\le10^6)\)的由\(\{-1,0,1\}\)组成的序列,你可以进行\(A_i+=A_{i-1}\)这样的操作, ...

  8. POI2013题解

    POI2013题解 只做了BZ上有的\(13\)道题. 就这样还扔了两道神仙构造和一道计算几何题.所以只剩下十道题了. [BZOJ3414][Poi2013]Inspector 肯定是先二分答案,然后 ...

  9. 【BZOJ3416】Poi2013 Take-out 栈

    [BZOJ3416]Poi2013 Take-out Description 小F喜欢玩一个消除游戏——take-out 保证k+1|n,保证输入数据有解这是一个单人游戏 游戏者的目标是消除初始时给定 ...

随机推荐

  1. FILE文件操作

    http://www.jb51.net/article/37688.htm fopen(打开文件)相关函数 open,fclose表头文件 #include<stdio.h>定义函数 FI ...

  2. centos 安装 py pyhs2

    1. yum install gcc-c++ cyrus-sasl-develpip2.7 install pyhs2 --->好像不行,在试试 用于 hive thrift 访问 2. os. ...

  3. hdu 2087剪花布条

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087 思路:正常KMP求解aaaaaa  aa得到的结果是6,这题是3.仅仅改一点代码就行 当匹配完之 ...

  4. EasyUi–8.datebox赋值的问题

    这个问题要从EasyUI的datebox组件说起,小菜用这个组件的时候,发现用$("#id").val()这种形式,居然拿不到文本框的值!      经过度娘的帮助,发现可以用$( ...

  5. TCP 四次握手

    TCP协议中的三次握手和四次挥手(图解) http://blog.csdn.net/whuslei/article/details/6667471/

  6. cutpFTP设置步骤

    cutpFTP设置步骤 平常时为了方便两台电脑之间传送数据,我们可以使用cutpftp这个工具实现,而且cutpftp还具有定时传送的功能,非常方便使用.以下是使用该工具的“同步文件夹”功能同步两台电 ...

  7. Android 注解工具 ButterKnife

    Butter Knife 是 Android 视图字段和方法绑定,使用注解处理来生成样板代码. 主要特性: 在字段使用 @FindView消除findViewById调用 使用 @FindViews在 ...

  8. iscroll 4.0 滚动(水平和垂直)

    1.概述 iscroll 专注于页面滚动js.Iscroll滚动做的挺好,特别是针对手机网页(android.iphone)正好弥补手动滑屏的遗缺,而今研究一番,把代码贴出来,供大家参考. 2.isc ...

  9. MyEclipse 选中右侧编辑的文件时自动展开左侧目录树

  10. Windows下Apache服务器中自动配置二级子域名

    今天我们介绍的这个办法,只需要简单修改 httpd-vhosts.conf 文件,配合 .htaccess 文件即可实现自动配置二级域名. 我们这里以 wpchina.com 为例,以下代码中的 wp ...