



Java代码:
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
private static ArrayList<String> cutpath = new ArrayList<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
ArrayList<Node> nodelist = new ArrayList<Node>();
for (int i = 0; i < n; i++) {
int id = sc.nextInt();
int val = sc.nextInt();
int pid = sc.nextInt();
Node node = new Node(id, val, pid);
if (id == 1) {
node.flag = true;
} else if (nodelist.get(pid - 1).flag) {
node.flag = false;
} else {
node.flag = true;
}
nodelist.add(node);
if (pid != -1) {
nodelist.get(pid - 1).childid.add(id);
}
}
sc.close();
go(nodelist);
for (int i = 0; i < nodelist.get(0).childid.size(); i++) {
if (nodelist.get(0).val == nodelist.get(nodelist.get(0).childid.get(i) - 1).val) {
System.out.println(
"1 " + nodelist.get(nodelist.get(0).childid.get(i) - 1).id + " " + nodelist.get(0).val);
break;
}
}
for (String s : cutpath) {
System.out.println(s);
}
}
public static void go(ArrayList<Node> nodelist) {
Node root = nodelist.get(0);
dfs(root, nodelist);
}
public static int dfs(Node node, ArrayList<Node> nodelist) {
if (!node.childid.isEmpty()) {// 非叶子结点
if (node.noused) {
if (node.flag) {
node.val = -999;
} else {
node.val = 999;
}
node.noused = false;
}
int s = node.childid.size();
// 遍历子结点
for (int i = 0; i < s; i++) {
/**
* 如果是极大结点(flag==true),从子节点获得的值大于兄弟结点,则后续子节点不必再遍历
* 如果是极小结点(flag==false),从子节点获得的值小于兄弟结点,同样剪枝 剪枝即输出该结点与子节点的序号 若是极大结点再输出beta
* 极小结点输出arlfa 然后continue; if(cut) { continue; }
*
*/
// 该结点不是根节点
if (node.parentid != -1) {
// 该结点无兄弟结点,则与爷结点的兄弟结点相比
int gpid=1;
if(node.id>7){
gpid = nodelist.get(nodelist.get(node.parentid - 1).parentid - 1).id;
}
boolean existgp=false;
if (node.id>7 && nodelist.get(node.parentid - 1).childid.size() == 1 && nodelist.get(nodelist.get(gpid-1).parentid-1).childid.get(0)!=gpid) {
existgp=true;
}
// 若是极大结点
if (node.flag) {
// 若该结点值大于之前任一兄弟结点,则不必再遍历该结点的子节点
boolean cut = false;
for (int j = 0; j < nodelist.get(node.parentid - 1).childid.indexOf(node.id); j++) {
if (node.val > nodelist.get(nodelist.get(node.parentid - 1).childid.get(j) - 1).val) {
cut = true;
break;
}
}
if (existgp && nodelist.get(node.parentid - 1).childid.size() == 1 && nodelist.get(nodelist.get(gpid-1).childid.get(0)-1).id!=gpid) {
if(node.val>nodelist.get(nodelist.get(nodelist.get(gpid-1).parentid-1).childid.get(0)-1).val)
{
cut=true;
}
}
if (cut) {
cutpath.add(node.id + " " + node.childid.get(i) + " beta");
continue;
}
} else {
// 若该结点值小于之前任一兄弟结点,则不必再遍历该结点的子节点
boolean cut = false;
for (int j = 0; j < nodelist.get(node.parentid - 1).childid.indexOf(node.id); j++) {
if (node.val < nodelist.get(nodelist.get(node.parentid - 1).childid.get(j) - 1).val) {
cut = true;
break;
}
}
if (existgp && nodelist.get(node.parentid - 1).childid.size() == 1 && nodelist.get(nodelist.get(gpid-1).childid.get(0)-1).id!=gpid) {
if(node.val<nodelist.get(nodelist.get(nodelist.get(gpid-1).parentid-1).childid.get(0)-1).val)
{
cut=true;
}
}
if (cut) {
cutpath.add(node.id + " " + node.childid.get(i) + " alpha");
continue;
}
}
}
int k = dfs(nodelist.get(node.childid.get(i) - 1), nodelist);
// 根据从子节点得到的信息,更改该结点的值
if (node.flag) {
if (k > node.val) {
node.val = k;
}
} else {
if (k < node.val) {
node.val = k;
}
}
}
return node.val;
} else {// 叶子结点
return node.val;
}
}
}
class Node {
public boolean noused = true;
public boolean flag;
public int parentid;
public int id;
public int val;
public ArrayList<Integer> childid = new ArrayList<>();
public Node() {
}
public Node(int id, int val, int pid) {
this.id = id;
this.val = val;
this.parentid = pid;
}
}
测试样例和输出:
39 1 0 -1 2 0 1 3 0 1 4 0 2 5 0 2 6 0 3 7 0 3 8 0 4 9 0 4 10 0 5 11 0 5 12 0 5 13 0 5 14 0 6 15 0 6 16 0 7 17 0 7 18 0 8 19 5 8 20 -3 9 21 3 9 22 3 10 23 -3 11 24 0 11 25 2 11 26 2 12 27 -3 12 28 0 12 29 -2 13 30 3 13 31 5 14 32 4 14 33 1 14 34 -3 15 35 0 15 36 6 16 37 8 16 38 9 17 39 -3 17 样例输出 1 3 1 9 21 alpha 5 11 beta 5 12 beta 5 13 beta 15 35 alpha 7 17 beta
原文:https://www.cnblogs.com/lemon-567/p/14724143.html