Editorial for Cây P đỉnh (Cơ bản)


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này

Code mẫu của flashmt

uses math;
const fi='';
      maxn=210;
var n,p,re:longint;
    a:array[1..maxn*2] of longint;
    pos,cur,sl,c,cha:array[1..maxn] of longint;
    b:array[1..maxn,0..1] of longint;
    f,tr:array[1..maxn,0..maxn] of longint;

procedure rf;
var i:longint;
begin
     read(n,p);
     for i:=1 to n do read(c[i]);
     for i:=1 to n-1 do
     begin
          read(b[i,0],b[i,1]);
          inc(sl[b[i,0]]); inc(sl[b[i,1]]);
     end;
     pos[1]:=1; cur[1]:=1;
     for i:=2 to n+1 do
     begin
          pos[i]:=pos[i-1]+sl[i-1];
          cur[i]:=pos[i];
     end;
     for i:=1 to n-1 do
     begin
          a[cur[b[i,0]]]:=b[i,1];
          inc(cur[b[i,0]]);
          a[cur[b[i,1]]]:=b[i,0];
          inc(cur[b[i,1]]);
     end;
end;

procedure visit(x,y:longint);
var i,j,k:longint;
begin
     cha[x]:=y;
     f[x,1]:=c[x];
     for i:=pos[x] to pos[x+1]-1 do
         if a[i]<>y then
         begin
              visit(a[i],x);
              for j:=p downto 2 do
                  for k:=1 to j-1 do
                      if f[x,j]<f[x,j-k]+f[a[i],k] then
                      begin
                           f[x,j]:=f[x,j-k]+f[a[i],k];
                           tr[a[i],j]:=k;
                      end;
         end;
end;

procedure trace(x,p:longint);
var i,j,k,val:longint;
begin
     write(x,' ');
     for i:=pos[x+1]-1 downto pos[x] do
         if (a[i]<>cha[x]) and (tr[a[i],p]>0) then
         begin
              trace(a[i],tr[a[i],p]);
              p:=p-tr[a[i],p];
         end;
end;

procedure pr;
var i,j,x:longint;
begin
     for i:=1 to n do
         for j:=1 to p do
             f[i,j]:=-1000000;
     visit(1,0);
     for i:=1 to n do
         if f[i,p]>re then
         begin
              re:=f[i,p];
              x:=i;
         end;
     trace(x,p);
end;

begin
     assign(input,fi); reset(input);
     rf;
     pr;
     close(input);
end.

Code mẫu của RR

uses math;
const
  oo            =       1000111000;

var
  n,p,i,u,v     :       longint;
  deg,c,father  :       array[1..222] of longint;
  ke,f,trace    :       array[1..222,0..222] of longint;

procedure visit(u:longint);
    var
      v,i,a,b,tmp:longint;
    begin
      f[u,0]:=0; f[u,1]:=c[u];
      for i:=1 to deg[u] do
        begin
          v:=ke[u,i];
          if f[v,0]=0 then continue;
          father[v]:=u;
          visit(v);
          for a:=p downto 1 do
          for b:=1 to a-1 do
            begin
              tmp:=f[v,b]+f[u,a-b];
              if tmp>f[u,a] then
                begin
                  f[u,a]:=tmp;
                  trace[v,a]:=b;
                end;
            end;
        end;
    end;

procedure print(u,k:longint);
    var
      v,i:longint;
    begin
      write(u,' ');
      for i:=deg[u] downto 1 do
        begin
          v:=ke[u,i];
          if v=father[u] then continue;
          if trace[v,k]>0 then
              print(v,trace[v,k]);
          dec(k,trace[v,k]);
        end;
    end;

procedure ans;
    var
      i,res:longint;
    begin
      res:=1;
      for i:=1 to n do
        if f[i,p]>f[res,p] then res:=i;

      print(res,p);
    end;

begin
  read(n,p);
  for u:=1 to n do
  for i:=0 to p do
    f[u,i]:=-oo;

  for i:=1 to n do read(c[i]);
  for i:=1 to n-1 do
    begin
      read(u,v);
      inc(deg[u]); inc(deg[v]);
      ke[u,deg[u]]:=v;
      ke[v,deg[v]]:=u;
    end;

  visit(1);
  ans;
end.

Code mẫu của hieult

#include <stdio.h>
//#include <conio.h>
#define maxn 201
#define maxc 1000000000
long c[maxn],d[maxn][maxn],n,P,a[maxn][maxn],trace[maxn][maxn];
//FILE *p;
void visit(long u)
{
//printf("0 ");     
d[u][1]=c[u];
for(long v=1;v<=n;v++)
  if(a[u][v]==1)
    {
    a[v][u]=0;
    visit(v);
    for(long i=P;i>=1;i--)
      for(long j=1;j<=i-1;j++)
        if(d[u][i]<d[u][j]+d[v][i-j])
          {
          d[u][i]=d[u][j]+d[v][i-j];
          trace[v][i]=i-j;
          }
    }
}
void truy_vet(long u,long P)
{
//printf("1 "); 
for(long v=n;v>=1;v--)
  if(a[u][v]==1&&trace[v][P]>0)
    {
    truy_vet(v,trace[v][P]);
    P=P-trace[v][P];
    }
printf("%ld ",u);
}
void xuli()
{
long u,vt;
visit(1);
vt=1;
for(u=2;u<=n;u++)
  if(d[u][P]>d[vt][P])
    vt=u;
  truy_vet(vt,P);
}
void init()
{
for(long u=1;u<=n;u++)
  for(long k=1;k<=n;k++)
    d[u][k]=-maxc;
} 
void Enter()
{
//p=fopen("D:\\Hoc tap\\test\\PTREE\\PTREE.IN0","r");
long i,u,v;
scanf("%ld %ld",&n,&P);
for(i=1;i<=n;i++)
  scanf("%ld",&c[i]);
for(i=1;i<=n-1;i++)
  {
  scanf("%ld %ld",&u,&v);
  a[u][v]=1;
  a[v][u]=1;
  }
}         
main()
{
Enter();
init();
xuli();
//getch();
}

Code mẫu của ll931110

{$MODE DELPHI}
program PTREE;
const
  input  = '';
  output = '';
  maxn = 200;
  maxv = 100000000;
var
  free: array[1..maxn] of boolean;
  c: array[1..maxn,1..maxn] of boolean;
  F,child: array[1..maxn,0..maxn] of integer;
  p,trace: array[1..maxn,1..maxn,0..maxn] of integer;
  n,k: integer;
  a,list,nchi: array[1..maxn] of integer;
  nlist: integer;

procedure init;
var
  fi: text;
  i,x,y,j,t: integer;
begin
  assign(fi, input);
    reset(fi);

  readln(fi, n, k);
  fillchar(c, sizeof(c), false);

  for i := 1 to n do read(fi, a[i]);
  for i := 1 to n - 1 do
    begin
      readln(fi, x, y);
      c[x,y] := true;
      c[y,x] := true;
    end;

  close(fi);

  for i := 1 to n do
    for j := 1 to n do
      for t := 1 to n do p[i,j,t] := -maxv;
  for i := 1 to n do
    for j := 1 to n do p[i,j,0] := 0;

  for i := 1 to n do
    for j := 1 to n do F[i,j] := -maxv;
  for i := 1 to n do F[i,0] := 0;

  fillchar(free, sizeof(free), true);
end;

procedure DFS(u: integer);
var
  v: integer;
begin
  free[u] := false;
  nchi[u] := 0;

  for v := 1 to n do
    if free[v] and c[u,v] then
      begin
        inc(nchi[u]);
        child[u,nchi[u]] := v;
        DFS(v);
      end;
end;

procedure dp(u: integer);
var
  i,j,t: integer;
begin
  if nchi[u] = 0 then
    begin
      F[u,1] := a[u];
      exit;
    end;

  for i := 1 to nchi[u] do dp(child[u,i]);
  for i := 0 to n do
    begin
      p[u,1,i] := F[child[u,1],i];
      trace[u,1,i] := i;
    end;

  for i := 2 to nchi[u] do
    for j := 0 to n do
      for t := 0 to j do
        if p[u,i,j] < p[u,i - 1,t] + F[child[u,i],j - t] then
          begin
            p[u,i,j] := p[u,i - 1,t] + F[child[u,i],j - t];
            trace[u,i,j] := j - t;
          end;

  for i := 1 to n - 1 do F[u,i] := p[u,nchi[u],i - 1] + a[u];
end;

procedure add(x: integer);
begin
  inc(nlist);
  list[nlist] := x;
end;

procedure track(u,val: integer);
var
  j,t: integer;
begin
  if val <= 1 then
    begin
      if val = 1 then add(u);
      exit;
    end;

  for j := nchi[u] downto 1 do
    begin
      t := trace[u,j,val - 1];
      val := val - t;
      track(child[u,j],t);
    end;
  add(u);
end;

procedure printresult;
var
  fo: text;
  i,j,t,u,max: integer;
begin
  assign(fo, output);
    rewrite(fo);

    max := -maxv;
    u := 0;
    for i := 1 to n do if max < F[i,k] then
      begin
        max := F[i,k];
        u := i;
      end;

    nlist := 0;
    track(u,k);

    for i := 1 to k - 1 do
      for j := i + 1 to k do
        if list[i] > list[j] then
          begin
            t := list[i];
            list[i] := list[j];
            list[j] := t;
          end;
    for i := 1 to k do write(fo, list[i], ' ');
  close(fo);
end;

begin
  init;
  DFS(1);
  dp(1);
  printresult;
end.

Code mẫu của khuc_tuan

import java.io.*;
import java.util.*;

public class Main {
    static int n,p;
    static int[] c, father;
    static ArrayList<Integer>[] ke;
    static int[][] f,d;
    static void dfs(int i) {
        int socon = 0;
        for(int j:ke[i]) if(j!=father[i]) {
            father[j]=i;
            dfs(j);
            ++socon;
        }
        if(socon==0) {
            f[i][1] = c[i];
            f[i][0] = 0;
            return;
        }
        int s=0;
        for(int j=1;j<=p;++j) d[0][j] = -20000000;
        for(int j:ke[i]) if(j!=father[i]) {
            ++s;
            for(int t=0;t<=p;++t) {
                d[s][t]=-20000000;
                for(int k=0;k<=t;++k) d[s][t]=Math.max(d[s][t],d[s-1][k]+f[j][t-k]);
            }
        }
        for(int t=1;t<=p;++t) f[i][t] = d[socon][t-1]+c[i];
        f[i][0] = 0;
    }
    static void truyvet(int i,int p) {
        if(p==0) return;
        int socon = 0;
        ArrayList<Integer> con=new ArrayList();
        for(int j:ke[i]) if(j!=father[i]) {
            ++socon;
            con.add(j);
        }
        if(socon==0) {
            System.out.print(i+" ");
            return;
        }
        System.out.print(i+" ");
        int s=0;
        for(int j=1;j<=p;++j) d[0][j] = -20000000;
        for(int j:ke[i]) if(j!=father[i]) {
            ++s;
            for(int t=0;t<=p;++t) {
                d[s][t]=-20000000;
                for(int k=0;k<=t;++k) d[s][t]=Math.max(d[s][t],d[s-1][k]+f[j][t-k]);
            }
        }
        int x=p-1;
        Stack<Integer> ss = new Stack();
        for(int j=socon;j>=1;--j) {
            for(int k=0;k<=x;++k) if(d[j-1][k]+f[con.get(j-1)][x-k] == d[j][x]) {
                ss.push(con.get(j-1));
                ss.push(x-k);
                x = k;
                break;
            }
        }
        while(!ss.isEmpty()){
            int b=ss.pop(), a=ss.pop();
            truyvet( a, b);
        }
    }
    public static void main(String[] Args) throws Exception {
        BufferedReader kb=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st=new StringTokenizer(kb.readLine());
        n = Integer.parseInt(st.nextToken());
        p = Integer.parseInt(st.nextToken());
        c = new int[n+1];
        st=new StringTokenizer(kb.readLine());
        for(int i=1;i<=n;++i) c[i] = Integer.parseInt(st.nextToken());
        ke = new ArrayList[n+1];
        for(int i=1;i<=n;++i) ke[i]=new ArrayList();
        for(int i=1;i<n;++i) {
            st=new StringTokenizer(kb.readLine());
            int u=Integer.parseInt(st.nextToken()), v=Integer.parseInt(st.nextToken());
            ke[u].add(v);
            ke[v].add(u);
        }
        f=new int[n+1][p+1];
        d=new int[n+1][p+1];
        for(int i=0;i<=n;++i) for(int j=0;j<=p;++j) f[i][j]=-20000000;
        father=new int[n+1];
        dfs(1);
        int res=0, imax=0;
        for(int i=1;i<=n;++i) if(res<f[i][p]) {
            res=f[i][p];
            imax=i;
        }
        truyvet(imax,p);
    }
}

Comments

Please read the guidelines before commenting.


There are no comments at the moment.