codeforces 23E 樹形DP

來源:互聯網
上載者:User

題目連結

給你一棵樹,讓你切斷一些邊,使得剩下的每個連通塊的點的個數的乘積最大,輸出這個乘積。

n <= 700

首先,答案肯定要用高精度儲存。。。。

可以貪心,也可以背包。

隨便畫一畫可以發現剩下的連通塊中,不會有某塊包含長度>=3的路徑,因為可以找到中間的那條邊切斷,使得這個路徑分成兩段a 和 b   (a>=2 ,b >=2), a*b>=a+b

根據這個推論 , 可以分三種情況

1:以u為根 ,且u與所有的兒子隔開

2::u與一些兒子相連,兒子們與孫子們都是斷開的,不然就會有>=3的路徑出現

3:u與某個兒子相連,然後這個兒子與一些孫子相連,再往下都是斷開的

假設h[i]為以i為子樹的答案    f[i]為 Πhj ,j是i的兒子

那麼對於第一種情況,答案為f[u],第二種情況的話u需要串連上一些子樹,串連某個兒子v的代價是f[u] / h[v] * f[v],所以如果只串連一個兒子,肯定就選f[v]/h[v]最大的那個兒子,因此可以先將所有的f[v]/h[v]排序,枚舉一遍就好了。

第三種情況與第二種類似。。。。

如果用背包做的話狀態大概是這樣的dp[i][j] 表示以i為根的子樹串連了j-1個兒子的最大乘積,(即i所在連通塊有j個點)。轉移的時候是最普通的那種轉移,不過這種做法顯然沒有注意到上面的推論。。。

import java.util.*;import java.math.*;import java.io.*;public class Main {    public static void main(String[] args) {        InputStream inputStream = System.in;        OutputStream outputStream = System.out;        InputReader in = new InputReader(inputStream);        PrintWriter out = new PrintWriter(outputStream);        AC solver = new AC();        solver.solve(in, out);        out.close();    }}class AC {    class Node {        BigInteger h, f;    }    Comparator<Integer> cmp = new Comparator<Integer>() {        public int compare(Integer a,Integer b) {               return dp[b].f.multiply(dp[a].h).compareTo(dp[a].f.multiply(dp[b].h));        }    };    ArrayList<Integer> edge[] = new ArrayList[710];    Node dp[] = new Node[710];    int size[] = new int[710];    void dfs(int u, int f,PrintWriter out) {        dp[u].f = dp[u].h = BigInteger.ONE;        size[u] = 1;     // case 1 : u's component is only u        for(int v:edge[u]) {             if(v == f) continue;            dfs(v,u,out);            dp[u].f = dp[u].f.multiply(dp[v].h);            size[u] += size[v];        }        Collections.sort(edge[u],cmp);     // case 2 : u is with some of its children        dp[u].h = dp[u].f;        BigInteger cur;        cur = dp[u].f;        int son = 0;         for(int v:edge[u]){            if(v==f) continue;            son ++;            cur = cur.divide(dp[v].h).multiply(dp[v].f);            BigInteger tmp = cur.multiply(BigInteger.valueOf(son+1));            if(tmp.compareTo(dp[u].h) > 0) dp[u].h = tmp;        }     // case 3: u is with only one of its children and some children's children                for(int v :edge[u]) {            if(v==f) continue;            cur = dp[u].f.divide(dp[v].h).multiply(dp[v].f);            son = 0;            for(int w : edge[v]) {                if(w == u) continue;                son++;                cur = cur.divide(dp[w].h).multiply(dp[w].f);                BigInteger tmp = cur.multiply(BigInteger.valueOf(son+2));                if(tmp.compareTo(dp[u].h) > 0) dp[u].h = tmp;            }        }     }    public void solve(InputReader in, PrintWriter out) {         int n, a, b;        n = in.nextInt();        for (int i = 1; i <= n; i++){            edge[i] = new ArrayList<Integer>();            dp[i] = new Node();        }        for (int i = 1; i < n; i++) {            a = in.nextInt();            b = in.nextInt();            edge[a].add(b);            edge[b].add(a);        }        dfs(1,0,out);        out.println(dp[1].h);    }}class InputReader {    BufferedReader reader;    StringTokenizer tokenizer;    public InputReader(InputStream stream) {        reader = new BufferedReader(new InputStreamReader(stream));        tokenizer = null;    }    public String next() {        while (tokenizer == null || !tokenizer.hasMoreTokens()) {            try {                tokenizer = new StringTokenizer(reader.readLine());            } catch (IOException e) {                throw new RuntimeException(e);            }        }        return tokenizer.nextToken();    }    public int nextInt() {        return Integer.parseInt(next());    }    public double nextDouble() {        return Double.parseDouble(next());    }    public long nextLong() {        return Long.parseLong(next());    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.