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

http://codeforces.com/contest/761/problem/E

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

 

思路:

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

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

 1 #include<iostream>
 2 #include<string>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cstdio>
 7 using namespace std;
 8 
 9 const int maxn=30+5;
10 
11 int n;
12 vector<int> g[maxn];
13 int vis[maxn];
14 long long ans_x[maxn],ans_y[maxn];
15 
16 int dx[]={0,-1,1,0};
17 int dy[]={-1,0,0,1};
18 
19 void dfs(int u,int fa_dir,long long dir)
20 {
21     vis[u]=1;
22     int k=0;
23     for(int i=0;i<g[u].size();i++)
24     {
25         int v=g[u][i];
26         if(!vis[v])
27         {
28             if(k==3-fa_dir)  k++;
29             ans_x[v]=ans_x[u]+dir*dx[k];
30             ans_y[v]=ans_y[u]+dir*dy[k];
31             dfs(v,k,dir/2);
32             k++;
33         }
34     }
35 }
36 
37 int main()
38 {
39     while(~scanf("%d",&n))
40     {
41         bool flag=true;
42         for(int i=1;i<=n;i++)  g[i].clear();
43         for(int i=0;i<n-1;i++)
44         {
45             int u,v;
46             scanf("%d%d",&u,&v);
47             g[u].push_back(v);
48             g[v].push_back(u);
49             if(g[u].size()>4 || g[v].size()>4)  flag=false;
50         }
51         if(!flag)  {puts("NO");continue;}
52         memset(vis,0,sizeof(vis));
53         ans_x[1]=0; ans_y[1]=0;
54         dfs(1,-1,1<<30);
55         puts("YES");
56         for(int i=1;i<=n;i++)
57             printf("%lld %lld\n",ans_x[i],ans_y[i]);
58     }
59     return 0;
60 }

 

posted @ 2017-05-21 19:43  Kayden_Cheung  阅读(146)  评论(0编辑  收藏  举报
//目录