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.



posted @ 2012-04-06 20:06  F.D.His.D  阅读(268)  评论(0编辑  收藏  举报