题解 CF761E 【Dasha and Puzzle】

这道题非常有意思。

首先存在点的度数 \(>4\) 即无解。

因为要和坐标轴平行,且要求路径不能相交,那么点显然更不能相交,但只有 \(4\) 个象限,最多只能向 \(4\) 个象限分别连一条边,所以当度数超过 \(4\) 的时候无解。

如何保证不相交?我们注意到 \(n\) 到数据范围特别小,只到 \(30\),相比之下边权到范围非常大。甚至 \(2^n\) 都是完全可以通过的。于是我们可以把根放在原点,边的长度为 \(2^{31-dep}\),向 \(4\) 个不同方向连出边。

DFS 一遍即可。

这道题就做完了!

代码非常简短:

#include<bits/stdc++.h>
#define log(a) cerr<<"\033[32m[DEBUG] "<<#a<<'='<<(a)<<" @ line "<<__LINE__<<"\033[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;
}
posted @ 2021-08-13 12:38  zhaohaikun  阅读(53)  评论(0编辑  收藏  举报