/*算法竞赛入门经典 例题 9-8 树的最大独立集
* d[i]表示以i为根的最大独立集的大小
* 为简便起见 默认输入的第一个节点是根节点
* 输入一条边时 第一个顶点是第二个顶点的父节点
* 节点编号 1...n
* */
import java.util.Arrays;
import java.util.Scanner;
class Node {
int num;
int parent;
int sumgs;// 孙子节点累加和
int sums;// 儿子节点累加和
public Node(int num, int parent) {
this.num = num;
this.parent = parent;
}
}
public class TreeMaxSet {
static final int MAXN = 100;// 最大节点数
static Node[] arr = new Node[MAXN];
static int n;// 实际节点数
static int m;// 边数
static int[][] g = new int[MAXN][MAXN];
static int[] d = new int[MAXN];
static boolean flag;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while ((n = scanner.nextInt()) > 0) {
Arrays.fill(d, 0);
for (int i = 1; i <= n; i++)
arr[i] = new Node(i, i);
m = scanner.nextInt();
for (int i = 0; i < m; i++) {
int u = scanner.nextInt();
int v = scanner.nextInt();
g[u][v] = 1;
arr[v].parent = u;
}
int max = 0, index = 0;
for (int i = 1; i <= n; i++) {// 对于每个节点更新其父亲和祖父节点的累加值
int t = dp(i);
int p = arr[i].parent;// 获得i的父亲节点的num
int pp = arr[p].parent;// 获得i祖父节点的num
if (pp == p && p != i) {
arr[p].sums += t;
} else if (pp != p) {
arr[p].sums += t;
arr[pp].sumgs += t;
}
if (arr[p].sums >= arr[pp].sumgs + 1 && arr[p].sums > max) {
max = arr[p].sums;
index = p;
flag = false;
} else if (arr[pp].sumgs + 1 > arr[p].sums
&& arr[pp].sumgs + 1 > max) {
max = arr[pp].sumgs + 1;
index = pp;
flag = true;
}
}
System.out.println("the max:" + max);
if(flag)
print(index);
else {
for(int i=1; i<=n; i++) {
if(g[index][i] == 1 && arr[i].parent == index)
print(i);
}
}
System.out.println();
}
}
private static int dp(int i) {
if (d[i] > 0)
return d[i];
d[i] = 1;
for (int j = 1; j <= n; j++) {
if (g[i][j] == 1) {// i是j的父亲 找出i的孙子
for (int k = 1; k <= n; k++) {
if (arr[k].parent == j)
d[i] += dp(k);
}
}
}
return d[i];
}
private static void print(int i) {
System.out.printf("%d ", i);
for (int j = 1; j <= n; j++) {
if (g[i][j] == 1 && arr[j].parent == i) {
for (int k = 1; k <= n; k++) {
if (arr[k].parent == j)
print(k);
}
}
}
}
}输入:
11
10
1 2 1 3 3 4 3 5 3 6 4 7 4 8 5 9 5 10 6 11
输出:
the max:7
2 3 7 8 9 10 11
算法竞赛入门经典 例题 9-8 树的最大独立集
最新推荐文章于 2025-07-03 02:19:09 发布