算法设计与分析: 3-25 树的最大连通分支问题

3-25 树的最大连通分支问题


给定一棵树 T,树中每个顶点 u 都有一个权 w(u),权可以是负数。现在要找到树 T 的一个连通子图使该子图的权之和最大。

对于给定的树 T,编程计算树 T 的最大连通分支。

数据输入:
第 1 行有 1 个正整数 n,表示树 T 有 n 个顶点。树 T 的顶点编号为 1,…,n。第 2 行有 n 个整数,表示 n 个顶点的权值。接下来的 n-1 行中,每 行有表示树 T 的一条边的 2 个整数 u,v,表示顶点 u 与顶点 v 相连。


Java

import java.util.Scanner;

public class ShuDeZuiDaLianTongFenZhi {

    private static class Node{
        int s;
        Node next;
    }

    private static int n;
    private static int[] w;
    private static Node[] child;
    private static int[] vis;

    private static int maxw;
    private static int[] sum;

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int a, b;

        while (true){
            maxw = 0;
            n = input.nextInt();
            w = new int[n+1];
            child = new Node[n+1];
            vis = new int[n+1];
            sum = new int[n+1];


            for(int i=1; i<=n; i++)
                w[i] = input.nextInt();

            for(int i=1; i<=n-1; i++){
                a = input.nextInt();
                b = input.nextInt();

                Node p = new Node();
                p.s = a;
                p.next = child[b];
                child[b] = p;
                p = new Node();
                p.s = b;
                p.next = child[a];
                child[a] = p;
            }

            build(1);
            comp(1);

            for(int i=1; i<=n; i++)
                if(sum[i] > maxw)
                    maxw = sum[i];

            System.out.println(maxw);
        }
    }

    private static void build(int k){
        Node p;
        Node q = new Node();
        vis[k] = 1;
        p = child[k];
        while (p != null){
            int i = p.s;
            if(vis[i] > 0)
                if(p == child[k]){
                    child[k] = p.next;
                    p = child[k];
                }
                else {
                    q.next = p.next;
                    p = q.next;
                }
            else{
                build(i);
                if(p == child[k])
                    q = child[k];
                else
                    q = q.next;
                p = p.next;
            }
        }
    }

    private static void comp(int k){
        Node p = child[k];
        while (p != null){
            int i = p.s;
            comp(i);
            if(sum[i] > 0)
                sum[k] += sum[i];
            p = p.next;
        }
        sum[k] += w[k];
    }
}

Input & Output

5
-1 1 3 1 -1
4 1
1 3
1 2
4 5
4

Reference

王晓东《计算机算法设计与分析》(第3版)P99

猜你喜欢

转载自blog.csdn.net/ioio_/article/details/81047828
今日推荐