CF761E

思路:

无解显然等价于存在点度大于 \(4\) 的节点,因为与 \((x,y)\) 关于坐标轴平行的点满足边不相交只有 \(4\) 个

钦定 \(1\) 为根

第一反应是边权要尽量大,要不然容易出现兄弟节点重合的情况,但由于边不能相交,所以边权要随着树的层数的增加不断减小,假设深度为 \(d\),\(i\) 和它子节点的连边的权值是 \(p_i\),那么应该满足对于任意 \(i\) ,都有 \(p_i > \sum_{i< k \leq d} p_k\),满足这个等式的构造方法是显然的,即对于任意 \(1\leq i\leq d\),满足\(p_i=2^{n-i+1}\),因为 \(n\) 很小,所以不必担心跑出 \(10^{18}\)。

现在每条边的权值已经得到,还需要考虑 \(u\) 的子节点的方向不能朝向 \(u\) 的父节点,记录来的方向即可。

代码:

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define ld long double
using namespace std;
int n,d[50];
bool f=0;
vector<int>edge[50];
struct node
{
	int x,y;
};
node p[50];
map<pair<int,int>,bool>m;
void dfs(int u,int fa,int len,int from)
{
	for(int i=0;i<edge[u].size();i++)
	{
		int v=edge[u][i];
		if(v==fa) continue;
		int f;
		if(!m[make_pair(p[u].x,p[u].y+len)]&&from!=4) p[v]=(node){p[u].x,p[u].y+len},m[make_pair(p[u].x,p[u].y+len)]=1,f=1;
		else if(!m[make_pair(p[u].x,p[u].y-len)]&&from!=1) p[v]=(node){p[u].x,p[u].y-len},m[make_pair(p[u].x,p[u].y-len)]=1,f=4;
		else if(!m[make_pair(p[u].x+len,p[u].y)]&&from!=3) p[v]=(node){p[u].x+len,p[u].y},m[make_pair(p[u].x+len,p[u].y)]=1,f=2; 
		else if(!m[make_pair(p[u].x-len,p[u].y)]&&from!=2) p[v]=(node){p[u].x-len,p[u].y},m[make_pair(p[u].x-len,p[u].y)]=1,f=3;
		dfs(v,u,len/2,f);
	}
}
signed main()
{
	cin>>n;
	for(int i=1;i<n;i++) 
	{
		int u,v;cin>>u>>v;
		edge[u].push_back(v);
		edge[v].push_back(u);
		d[u]++,d[v]++;
	}
	for(int i=1;i<=n;i++)
	{
		if(d[i]>4) f=1;
	}
	if(f==1) puts("NO");
	else 
	{
		puts("YES");
		p[1]=(node){0,0};m[make_pair(0,0)]=1;
		dfs(1,0,2147483647,0);
//		for(int i=1;i<=n;i++) cout<<d[i]<<" ";
//		puts("");
		for(int i=1;i<=n;i++) cout<<p[i].x<<" "<<p[i].y<<"\n";
	}
}
上一篇:EasyUI控件easyui-tabs动态添加tab时有滚动条的问题


下一篇:北京专精特新企业有多少奖励及好处重点介绍,补贴20-50万