这道题非常有意思。
首先存在点的度数 (>4) 即无解。
因为要和坐标轴平行,且要求路径不能相交,那么点显然更不能相交,但只有 (4) 个象限,最多只能向 (4) 个象限分别连一条边,所以当度数超过 (4) 的时候无解。
如何保证不相交?我们注意到 (n) 到数据范围特别小,只到 (30),相比之下边权到范围非常大。甚至 (2^n) 都是完全可以通过的。于是我们可以把根放在原点,边的长度为 (2^{31-dep}),向 (4) 个不同方向连出边。
DFS 一遍即可。
这道题就做完了!
代码非常简短:
#include<bits/stdc++.h>
#define log(a) cerr<<" 33[32m[DEBUG] "<<#a<<'='<<(a)<<" @ line "<<__LINE__<<" 33[0m"<<endl
#define LL long long
#define SZ(x) ((int)x.size()-1)
#define ms(a,b) memset(a,b,sizeof a)
#define F(i,a,b) for(int i=(a);i<=(b);++i)
#define DF(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
inline int read(){char ch=getchar(); int w=1,c=0;
for(;!isdigit(ch);ch=getchar()) if (ch=='-') w=-1;
for(;isdigit(ch);ch=getchar()) c=(c<<1)+(c<<3)+(ch^48);
return w*c;
}
const int N=35;
vector<int>v[N];
int dep[N],h[N];LL kx[N],ky[N];
void dfs(int x,int fa){
dep[x]=dep[fa]+1;
LL k=(1ll<<(30-dep[x]));
int z=-1;
F(i,0,SZ(v[x]))
if(v[x][i]!=fa){
kx[v[x][i]]=kx[x];
ky[v[x][i]]=ky[x];
z++;
if(z==(h[x]^1))z++;
h[v[x][i]]=z;
if(z==0)kx[v[x][i]]+=k;
if(z==1)kx[v[x][i]]-=k;
if(z==2)ky[v[x][i]]+=k;
if(z==3)ky[v[x][i]]-=k;
dfs(v[x][i],x);
}
}
signed main(){
int n=read();
F(i,2,n){
int x=read(),y=read();
v[x].push_back(y);
v[y].push_back(x);
}
F(i,1,n)
if(v[i].size()>4){
puts("NO");
return 0;
}
h[1]=-1;
dfs(1,0);
puts("YES");
F(i,1,n)cout<<kx[i]<<" "<<ky[i]<<endl;
return 0;
}