http://codeforces.com/contest/761/problem/E
给出一颗树,要求在坐标系中用平行于坐标轴的线描绘出来。
要求边不能相交,而且点的坐标唯一。
注意到2^1 + 2^2 + ..... + 2^n = 2^(n + 1) - 1
那就是说,如果第一条边的边长是2^(n + 1),那么后面的边选2^n 、 2^(n - 1)等等,相加起来也不会越过第一条,所以也就不会相交。
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <assert.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> #include <bitset> const int maxn = 30 + 20; struct node { int u, v, tonext; } e[maxn * 2]; int num; int first[maxn]; void add(int u, int v) { ++num; e[num].u = u; e[num].v = v; e[num].tonext = first[u]; first[u] = num; } struct coor { LL x, y; coor(LL xx, LL yy) : x(xx), y(yy) {} bool operator < (const struct coor & rhs) const { if (x != rhs.x) return x < rhs.x; else return y < rhs.y; } }; vector<struct coor>ans[maxn]; int tonext[4][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}}; bool vis[maxn]; const LL one = 1; int haha[4]; void dfs(int cur, LL x, LL y, int son, int pre) { ans[cur].push_back(coor(x, y)); // aler.insert(coor(x, y)); vis[cur] = true; int to = 0; for (int i = first[cur]; i; i = e[i].tonext) { int v = e[i].v; if (vis[v]) continue; if (to == pre) to++; if (to == 4) to = 0; dfs(v, x + tonext[to][0] * (one << son), y + tonext[to][1] * (one << son), son - 1, haha[to]); to++; } } void work() { haha[0] = 2; haha[1] = 3; haha[2] = 0; haha[3] = 1; int n; scanf("%d", &n); for (int i = 1; i <= n - 1; ++i) { int u, v; scanf("%d%d", &u, &v); add(u, v); add(v, u); } for (int i = 1; i <= n; ++i) { int t = -1; for (int j = first[i]; j; j = e[j].tonext) { t++; } if (t >= 4) { // cout << t << endl; cout << "NO" << endl; return; } } // LL y = 1 << 30; // y <<= 2; // cout << y << endl; dfs(1, 1, 1, 32, -1); cout << "YES" << endl; for (int i = 1; i <= n; ++i) { // if (ans[i].size() == 0) { // cout << i << "ffff" << endl; // continue; // } cout << ans[i][0].x << " " << ans[i][0].y << endl; } } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif work(); return 0; }