zoukankan      html  css  js  c++  java
  • POJ 1192

    POJ 1192

    Noi的题>.<

    题目大意:给出一些点,坐标都是整数,如果两个点的距离为1,则说明相邻..(省略繁琐题意),删点后连通……总之就是构建了一棵树,每个节点有一个权值,求这棵树的一颗子树,有权值最大。

    解:首先说下自己的二点,没看到树的性质(每两个点有且只有一条路径联通),然后刚刚切完一系列的双连通分量,很激动的用贪心,每次去除掉一个当前权值最小且非割点的的点=。=然后wa掉,检查半天,最后看discuss才知道完全是自己的题意理解错了,况且如果是图我这个是从本质上贪心不能,因为有时不一定去点,还可以有整个枝条不要的情况,每次去一个点贪心是做不到的,正解treedp,fjy出的题那个第三题的更新与这个类似,O(n)即可,不过小心第一次dfs构树的时候可能会爆栈。

    研究了一下_gxx的程序,自己又二了,实际上是不用考虑父亲的,因为在父亲的时候就会包含这种情况了,因为在x时,opt{(pre[x] + opt(左子)) + x},而站在pre[x]时,opt{pre[x], 左子, 右子} == opt{opt{pre[x], left}, right},因此只用求一个拓扑序,然后自下向上更新即可。

    View Code
     1 const
    2 maxn=1111;
    3 maxm=maxn*2;
    4 type
    5 data=record
    6 dest, next: longint;
    7 end;
    8 po=record
    9 x, y: longint;
    10 end;
    11 var
    12 edge: array[1..maxm]of data;
    13 f, pre, cost, vect: array[1..maxn]of longint;
    14 point: array[1..maxn]of po;
    15 n, m, ans, tot: longint;
    16 procedure add(x, y: longint);
    17 begin
    18 inc(tot);
    19 with edge[tot] do begin
    20 dest := y;
    21 next := vect[x];
    22 vect[x] := tot;
    23 end;
    24 inc(tot);
    25 with edge[tot] do begin
    26 dest := x;
    27 next := vect[y];
    28 vect[y] := tot;
    29 end;
    30 end;
    31
    32 procedure init;
    33 var
    34 i, j: longint;
    35 begin
    36 ans := 0; tot := 0;
    37 fillchar(vect, sizeof(vect), 0);
    38 readln(n);
    39 for i := 1 to n do with point[i] do readln(x, y, cost[i]);
    40 for i := 1 to n-1 do
    41 for j := i + 1 to n do
    42 if (abs(point[i].x-point[j].x)+abs(point[i].y-point[j].y)=1) then add(i, j);
    43 end;
    44
    45 procedure dfs(x: longint);
    46 var
    47 i, tmp: longint;
    48 begin
    49 i := vect[x];
    50 tmp := cost[x];
    51 while i<>0 do
    52 with edge[i] do begin
    53 if dest<>pre[x] then begin
    54 pre[dest] := x;
    55 dfs(dest);
    56 if f[dest]>0 then tmp := tmp + f[dest];
    57 end;
    58 i := next;
    59 end;
    60 f[x] := tmp;
    61 end;
    62
    63 procedure main;
    64 var
    65 i, u, tmp: longint;
    66 begin
    67 fillchar(pre, sizeof(pre), 0);
    68 fillchar(f, sizeof(f), 0);
    69 dfs(1);
    70 for u := 1 to n do begin
    71 tmp := cost[u];
    72 i := vect[u];
    73 while i<>0 do
    74 with edge[i] do begin
    75 if pre[u]<>dest then begin
    76 tmp := tmp + f[dest];
    77 end;
    78 i := next;
    79 end;
    80 if pre[u]<>0 then begin
    81 tmp := tmp + (f[pre[u]]-f[u]);
    82 end;
    83 if tmp > ans then ans := tmp;
    84 end;
    85 end;
    86
    87 procedure print;
    88 begin
    89 writeln(ans);
    90 end;
    91
    92 begin
    93 assign(input,'1.txt'); reset(input);
    94 init;
    95 main;
    96 print;
    97 end.



  • 相关阅读:
    php max()函数 语法
    php min()函数 语法
    php mt_rand()函数 语法
    php rand()函数 语法
    php pi()函数 语法
    php trim()函数 语法
    php chop()函数 语法
    php rtrim()函数 语法
    php ltrim()函数 语法
    php is_file()函数 语法
  • 原文地址:https://www.cnblogs.com/wmzisfoolish/p/2435204.html
Copyright © 2011-2022 走看看