您的位置:首页 > 其它

Codeforces Round #394 (Div. 2) E. Dasha and Puzzle(dfs)

2017-05-21 19:43 316 查看
http://codeforces.com/contest/761/problem/E

题意:
给出一棵树,现在要把这棵树上的结点放置在笛卡尔坐标上,使得每一条边与x轴平行或者与y轴平行。输出可行解,即每个点放置的坐标。

思路:

一开始我想,这个每条边的边长都是可长可短的,好像很麻烦啊。

做法还是很巧妙的,因为最多也就30个点,所以我们直接让该点连接的边未len长度,然后dfs它的子节点并使它的子节点的边长为len/2。你会发现,这样线段就不会相交了。

#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstdio>
using namespace std;

const int maxn=30+5;

int n;
vector<int> g[maxn];
int vis[maxn];
long long ans_x[maxn],ans_y[maxn];

int dx[]={0,-1,1,0};
int dy[]={-1,0,0,1};

void dfs(int u,int fa_dir,long long dir)
{
vis[u]=1;
int k=0;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(!vis[v])
{
if(k==3-fa_dir)  k++;
ans_x[v]=ans_x[u]+dir*dx[k];
ans_y[v]=ans_y[u]+dir*dy[k];
dfs(v,k,dir/2);
k++;
}
}
}

int main()
{
while(~scanf("%d",&n))
{
bool flag=true;
for(int i=1;i<=n;i++)  g[i].clear();
for(int i=0;i<n-1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
if(g[u].size()>4 || g[v].size()>4)  flag=false;
}
if(!flag)  {puts("NO");continue;}
memset(vis,0,sizeof(vis));
ans_x[1]=0; ans_y[1]=0;
dfs(1,-1,1<<30);
puts("YES");
for(int i=1;i<=n;i++)
printf("%lld %lld\n",ans_x[i],ans_y[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: