CF#418 Div2 D. An overnight dance in discotheque

来源:互联网 发布:js获取frame 编辑:程序博客网 时间:2024/06/07 12:45

一道树形dp裸体,自惭形秽没有想到
首先由于两两圆不能相交(可以相切)就决定了一个圆和外面一个圆的包含关系
又可以发现这样的树中,奇数深度的圆+S,偶数深度的圆-S
就可以用树形dp

我又写挫了= =

#include<cmath>#include<map>#include<iostream>#include<cstring>#include<cstdio>#include<set>#include<vector>#include<queue>#include<stack>#include<algorithm>using namespace std;typedef long long ll;const int N = 1e3+5;const int INF = 0x3f3f3f3f;const double pi = acos(-1.0);#define MP(x, y) make_pair(x, y)int X[N], Y[N], R[N]; int ord[N];double S[N];struct Node{    int to, nx;}E[N*2];int head[N], tot;int dep[N];double dp[N][2][2];int cmp(int a, int b) {    return R[a] < R[b];}void gmax(double &a, double b) {    if(a < b) a = b;}void add(int fr, int to) {    E[tot].to = to; E[tot].nx = head[fr]; head[fr] = tot++;    dep[to] ++;}int Incir(int a, int b) {    if(R[a] <= R[b]) return 0;    double dis = sqrt(1ll*(X[a] - X[b])*(X[a] - X[b]) + 1ll*(Y[a] - Y[b])*(Y[a] - Y[b]));    if(dis + 1.0*R[b] <= 1.0*R[a]) return 1;    else return 0;}void dfs(int x) {    double tmp[2][2][2];    memset(tmp, 0, sizeof(tmp));    for(int i = head[x]; ~i; i = E[i].nx) {        int to = E[i].to; dfs(to);    }    for(int i = head[x]; ~i; i = E[i].nx) {        int to = E[i].to;        tmp[1][0][0] += dp[to][1][0]; tmp[1][0][1] += dp[to][1][1]; tmp[1][1][0] += dp[to][0][0]; tmp[1][1][1] += dp[to][0][1];        tmp[0][0][0] += dp[to][0][1]; tmp[0][0][1] += dp[to][0][0]; tmp[0][1][0] += dp[to][1][1]; tmp[0][1][1] += dp[to][1][0];     }    for(int i = 0; i < 2; ++i) for(int j = 0; j < 2; ++j) dp[x][i][j] = max(tmp[0][i][j] +( (j^1)? S[x]:-S[x]), tmp[1][i][j] +( (i^1)?S[x]:-S[x]));//  printf("%d %.2f %.2f %.2f %.2f %.2f %.2f\n",x, dp[x][0][0], dp[x][0][1], dp[x][1][0], dp[x][1][1], tmp[1][0][0] +( (0^1)?S[x]:-S[x]), S[x]);}int main() {    int n;    while(~scanf("%d", &n)) {        memset(dep, 0, sizeof(dep));        memset(head, -1, sizeof(head));        tot = 0;        for(int i = 0; i < n; ++i) {            scanf("%d %d %d", &X[i], &Y[i], &R[i]);            ord[i] = i;            S[i] = pi*R[i]*R[i];        }        sort(ord, ord+n, cmp);    //  for(int i = 0; i < n; ++i) printf("%d ", ord[i]); printf("\n");        for(int i = 0; i < n; ++i) {            for(int j = i+1; j < n; ++j) {                if(Incir(ord[j], ord[i])) { add(ord[j], ord[i]); break; }            }        }        double ans = 0;        for(int i = 0; i < n; ++i) {            if(!dep[i]) {                dfs(i);                ans += dp[i][0][0];            }        }        printf("%.9f\n", ans);    }       return 0;}
阅读全文
0 0