zoukankan      html  css  js  c++  java
  • poj2054 Color a Tree ****

      1 /*
    2 * POJ-2054 color a tree
    3 *
    4 * 贪心 难题!
    5 *
    6 * 思路1:
    7 * http://hi.baidu.com/cheezer94/blog/item/d98eca065202a2f237d122da.html
    8 * 思路2:
    9 * http://www.cnblogs.com/X-Kly/archive/2011/11/02/POJ2054.html
    10 * 代码:
    11 * http://xinbaolianmeng.com/showshouye.aspx?type=7&ID=110
    12 *
    13 * 简单讲:
    14 * 每次找到 权值最大的“集合”, 与其“父集合”合并, 权值为 两个集合中 顶点权值的平均。
    15 * 直到只剩一个集合
    16 *
    17 *
    18 * 下面有范例代码, 一样, 可看其注释
    19 *
    20 *
    21 */
    22
    23
    24 #include <cstdio>
    25 using namespace std;
    26
    27 const int maxn = 1000 + 5;
    28
    29 int n, r;
    30 int c[maxn], fa[maxn];
    31 int pre[maxn], next[maxn], sum[maxn], num[maxn];
    32 bool vis[maxn];
    33
    34 int find_max(){
    35 double max = -1;
    36 int maxNum = -1;
    37 for(int i=1; i<=n; i++){
    38 if(!vis[i] && (sum[i] * 1.0 / num[i]) > max){
    39 max = (sum[i] * 1.0 / num[i]);
    40 maxNum = i;
    41 }
    42 }
    43 return maxNum;
    44 }
    45
    46
    47 void unionFa(int x){
    48 int faSet;
    49 for(faSet=fa[x]; pre[faSet]!=-1; faSet = pre[faSet]);
    50 sum[faSet] += sum[x];
    51 num[faSet] += num[x];
    52 for(faSet=fa[x]; next[faSet]!=-1; faSet = next[faSet]);
    53 next[faSet] = x;
    54 pre[x] = faSet;
    55
    56 vis[x] = 1;
    57 }
    58
    59 int main(){
    60 while(scanf("%d%d", &n, &r)){
    61 if(n == 0) return 0;
    62
    63 for(int i=1; i<=n; i++){ //注意从1开始!!(因为输入的根、边的标号都是从1开始的)
    64 scanf("%d", &c[i]);
    65 sum[i] = c[i];
    66 num[i] = 1;
    67 pre[i] = next[i] = -1;
    68 vis[i] = false;
    69 }
    70
    71 int u, v;
    72 for(int i=1; i<n; i++){
    73 scanf("%d%d", &u, &v);
    74 fa[v] = u;
    75 }
    76
    77 int d;
    78 vis[r] = 1;
    79 while(1){
    80 d = find_max();
    81 if(d == -1) break;
    82 unionFa(d);
    83 }
    84
    85 int ans = 0, t = 1;
    86 for(int i=r; i!=-1; i=next[i]){
    87 ans += t * c[i];
    88 t++;
    89 }
    90 printf("%d\n", ans);
    91 }
    92
    93
    94 return 0;
    95 }
    96
    97 /* ===================== 范例程序 有注释 ================================
    98
    99 #include<iostream>
    100   #include <cstdio>
    101 using namespace std;
    102 const int max_n=1010;
    103 int pre[max_n];//pre[i]用来表示当前集合(包含i)的上个元素
    104 int next[max_n];//next[i]用来表示当前集合(包含i)的下个元素
    105 int c[max_n];
    106 int num[max_n];//num[i]表示当前集合(包含i)的元素个数
    107 int visit[max_n];
    108 int sum[max_n];//当前集合元素和
    109 int father[max_n];//father[i]表示i的父元素
    110 int n,r;
    111 int find_max()//找到当前权值最大的集合,合并后的点当做一个集合,也就是一个点
    112 {
    113 double max=0;
    114 int bh=-1;
    115 for(int i=1;i<=n;i++)
    116 {
    117 if(max<(sum[i]*1.0)/num[i]&&visit[i]==0)
    118 {
    119 max=(sum[i]*1.0)/num[i];
    120 bh=i;
    121 }
    122 }
    123 return bh;
    124 }
    125 void uni(int x)//联合
    126 {
    127 int i;
    128 for(i = father[x]; pre[i] != -1; i = pre[i]);//找到父元素所在的集合
    129 sum[i]+=sum[x];
    130 num[i]+=num[x];
    131 for(i = father[x]; next[i] != -1; i = next[i]);//找到父元素所在集合的底元素
    132 next[i]=x;
    133 pre[x]=i;
    134 visit[x]=1;
    135 }
    136 int main()
    137 {
    138
    139 while(scanf("%d %d",&n,&r),n&&r)
    140 {
    141 for(int i=1;i<=n;i++)
    142 {
    143 scanf("%d",&c[i]);
    144 sum[i]=c[i];
    145 visit[i] =0;
    146 pre[i] = next[i] = -1;
    147 num[i] = 1;
    148 }
    149 for(int i = 1; i < n; i++)
    150 {
    151 int a, b;
    152 scanf("%d %d", &a, &b);
    153 father[b] = a;
    154 }
    155
    156 int d;
    157 visit[r]=1;
    158 while(1)
    159 {
    160 d=find_max();
    161 if(d==-1)break;
    162 uni(d);
    163 }
    164 int ans=0,tjq=1;
    165 for(int i=r;i!=-1;i=next[i])
    166 {
    167 ans+=tjq*c[i];
    168 tjq++;
    169 }
    170 printf("%d\n",ans);
    171 }
    172
    173 return 0;
    174 }
    175
    176 */
  • 相关阅读:
    hadoop中namenode发生故障的处理方法
    开启虚拟机所报的错误:VMware Workstation cannot connect to the virtual machine. Make sure you have rights to run the program, access all directories the program uses, and access all directories for temporary fil
    Hbase的安装与部署(集群版)
    分别用反射、编程接口的方式创建DataFrame
    用Mapreduce求共同好友
    SparkSteaming中直连与receiver两种方式的区别
    privot函数使用
    Ajax无刷新显示
    使用ScriptManager服务器控件前后台数据交互
    数据库知识
  • 原文地址:https://www.cnblogs.com/longdouhzt/p/2390554.html
Copyright © 2011-2022 走看看