zoukankan      html  css  js  c++  java
  • POJ 3099 Go Go Gorelians

    http://poj.org/problem?id=3099

    树的重心:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心

    求树的重心

    如何在点中构造符合条件的树

    得到树后 从任意一个点出发 dfs一次找到离这个点最远的点作为root1

    在以root1出发 同样的方式求得root2

    root1-root2就是这个树的直径 那么中心必然在这个直径上, 如果直径上点的个数是奇数的话那么 这个点就是重心 否则有两个重心 分别输出

      1 #include <iostream>
      2 #include <string.h>
      3 #include <stdio.h>
      4 #include <vector>
      5 #include <math.h>
      6 #define MAXN 1007
      7 
      8 using namespace std;
      9 
     10 int dp[MAXN];
     11 int id[MAXN];
     12 int pre[MAXN];
     13 double dist[MAXN][MAXN];
     14 double x[MAXN], y[MAXN], z[MAXN];
     15 int path[MAXN];
     16 int n;
     17 vector<int> G[MAXN];
     18 
     19 double getdis(int i, int j)
     20 {
     21     double dx = x[i] - x[j];
     22     double dy = y[i] - y[j];
     23     double dz = z[i] - z[j];
     24     return sqrt(dx*dx+dy*dy+dz*dz);
     25 }
     26 
     27 void build()
     28 {
     29     for(int i = 0; i < n; i++)
     30     {
     31         double dis = 0x3fffffff;
     32         int obj = -1;
     33         for (int j = 0; j < i; j++)
     34         {
     35             if (dist[id[i]][id[j]] < dis)
     36             {
     37                 dis = dist[id[i]][id[j]];
     38                 obj = j;
     39             }
     40         }
     41         if (obj == -1) continue;
     42         int u = id[i], v = id[obj];
     43         G[u].push_back(v);
     44         G[v].push_back(u);
     45     }
     46 }
     47 void dfs(int x, int par, int len)
     48 {
     49     dp[x] = len;
     50     for (int i = 0; i < G[x].size(); i++)
     51     {
     52         if (G[x][i] != par)
     53             dfs(G[x][i], x, len+1);
     54     }
     55 
     56 }
     57 
     58 
     59 void dfs1(int x, int par, int len)
     60 {
     61     dp[x] = len;
     62     pre[x] = par;
     63     for (int i = 0; i < G[x].size(); i++)
     64     {
     65         if(G[x][i] != par)
     66             dfs1(G[x][i], x, len+1);
     67     }
     68 }
     69 int main()
     70 {
     71     while (~scanf("%d", &n))
     72     {
     73         if (n == 0) break;
     74         memset(dp, 0, sizeof(dp));
     75         memset(path, 0, sizeof(path));
     76         memset(dist, 0, sizeof(dist));
     77         memset(pre, 0, sizeof(pre));
     78         for (int i = 0; i < MAXN; i++)
     79             G[i].clear();
     80         for (int i = 0; i < n; i++)
     81         {
     82             scanf("%d%lf%lf%lf", &id[i], &x[i], &y[i], &z[i]);
     83         }
     84         for (int i = 0; i < n; i++)
     85             for (int j = 0; j < n; j++)
     86                 dist[id[i]][id[j]] = getdis(i, j);
     87         build();
     88         dfs(id[0], -1, 0);//权值都为1
     89         int tmp = 0;
     90         //找到离节点最远的节点 得到root1
     91         int root1, root2;
     92         for (int i = 0; i < n; i++)
     93         {
     94             if ( dp[id[i]] > tmp)
     95             {
     96                 tmp = dp[id[i]];
     97                 root1 = id[i];
     98             }
     99         }
    100         memset(dp, 0, sizeof(dp));
    101         dfs1(root1, -1, 0);
    102         tmp = 0;
    103         for (int i = 0; i < n; i++)
    104         {
    105             if (dp[id[i]] > tmp)
    106             {
    107                 tmp = dp[id[i]];
    108                 root2 = id[i];
    109             }
    110         }//找到root2;
    111         int s = 0;
    112         for(int i = root2; i != -1; i = pre[i])
    113         {
    114             path[++s] = i;
    115         }
    116         int mid = (s+1)/2;
    117         if (s % 2 == 1)
    118         {
    119             printf("%d
    ", path[mid]);
    120         }
    121         else
    122         {
    123             int a = path[mid], b = path[mid+1];
    124             printf("%d %d
    ", min(a, b), max(a, b));
    125         }
    126 
    127     }
    128 
    129     return 0;
    130 }

    关于树的重心更多的内容

    转载 :http://www.cnblogs.com/patrickzhou/p/5867208.html

  • 相关阅读:
    FZU 2098 刻苦的小芳(卡特兰数,动态规划)
    卡特兰数总结
    FZU 1064 教授的测试(卡特兰数,递归)
    HDU 4745 Two Rabbits(区间DP,最长非连续回文子串)
    Java 第十一届 蓝桥杯 省模拟赛 正整数的摆动序列
    Java 第十一届 蓝桥杯 省模拟赛 反倍数
    Java 第十一届 蓝桥杯 省模拟赛 反倍数
    Java 第十一届 蓝桥杯 省模拟赛 反倍数
    Java 第十一届 蓝桥杯 省模拟赛 凯撒密码加密
    Java 第十一届 蓝桥杯 省模拟赛 凯撒密码加密
  • 原文地址:https://www.cnblogs.com/oscar-cnblogs/p/6746211.html
Copyright © 2011-2022 走看看