Codeforces 196C Paint Tree(貪心+極角排序)
阿新 • • 發佈:2017-07-22
cpp namespace paint 進行 滿足 sin its force 一個個
題目鏈接 Paint Tree
給你一棵n個點的樹和n個直角坐標系上的點,現在要把樹上的n個點映射到直角坐標系的n個點中,要求是除了在頂點處不能有線段的相交。
我們先選一個在直角坐標系中的最左下角的點,把根結點放到這個點中,然後對剩下的點進行極角排序,按逆時順序一個個塞進來,類似地遞歸處理。
這樣就滿足了題意。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const int N = 1510; int X, Y; struct node{ int x, y; int id; friend bool operator < (const node &a, const node &b){ return (LL)(a.y - Y) * (b.x - X) < (LL)(b.y - Y) * (a.x - X); } } p[N]; vector <int> v[N]; int sz[N], ans[N]; int n; void dfs(int x, int fa){ sz[x] = 1; for (auto u : v[x]){ if (u == fa) continue; dfs(u, x); sz[x] += sz[u]; } } void calc(int x, int fa, int l, int r){ int t = l; rep(i, l + 1, r){ if (p[i].y < p[t].y || (p[t].y == p[i].y && p[i].x < p[t].x)) t = i; } if (t != l) swap(p[l], p[t]); ans[p[l].id] = x; X = p[l].x, Y = p[l].y; sort(p + l + 1, p + r + 1); int pos = l + 1; for (auto u : v[x]){ if (u == fa) continue; calc(u, x, pos, pos + sz[u] - 1); pos += sz[u]; } } int main(){ scanf("%d", &n); rep(i, 1, n - 1){ int x, y; scanf("%d%d", &x, &y); v[x].push_back(y); v[y].push_back(x); } rep(i, 1, n){ int x, y; scanf("%d%d", &x, &y); p[i] = {x, y, i}; } dfs(1, 0); calc(1, 0, 1, n); rep(i, 1, n) printf("%d\n", ans[i]); return 0; }
Codeforces 196C Paint Tree(貪心+極角排序)