This problem is, finding the minimal number of guards to set in a tree which can prevent prisoners escaping to tree leaves.
Time bound and space bound are both O(N).
Analysis
Create a Node structure, holding its parent index, a boolean value presenting it is a prisoner or not. Then a boolean value presenting whether prisoners can escape down to leaves, and another boolean value presenting whether prisoners can escape from the root.
Depth-First-Search from node 0.
Adjust the result according to node 0’s state. Done.
staticintN=200003;boolean[]visited=newboolean[N];Node[]nodes=newNode[N];intres=0;publicintsolution(intA[],intB[],intC[]){for(inti=0;i<A.length;i++){if(nodes[A[i]]==null)nodes[A[i]]=newNode();if(nodes[B[i]]==null)nodes[B[i]]=newNode();nodes[A[i]].tlist.add(B[i]);nodes[B[i]].tlist.add(A[i]);}if(C.length==0)return0;// if a prison is on leaf(exit), then we cannot stop them escapingfor(inti=0;i<C.length;i++){if(isLeaf(nodes[C[i]])){return-1;}nodes[C[i]].isPrisoner=true;}dfs(0);// if node 0 is has only one path, then it is an exit. // we should set a guard if node 0 is exit && prisoners can escape to rootreturnnodes[0].hasEscapeRoot&&nodes[0].tlist.size()==1?res+1:res;}voiddfs(intnodeIndex){visited[nodeIndex]=true;Nodenode=nodes[nodeIndex];for(inti=0;i<node.tlist.size();i++){intnextNodeIndex=node.tlist.get(i);if(!visited[nextNodeIndex]){nodes[nextNodeIndex].parentIndex=nodeIndex;dfs(nextNodeIndex);}}if(nodeIndex!=node.parentIndex&&(isLeaf(node)))return;intn=0;intescapesLeaf=0;intescapesRoot=0;for(inti=0;i<node.tlist.size();++i){intnext=node.tlist.get(i);if(node.parentIndex==next)continue;n++;if(nodes[next].hasEscapeLeaf)escapesLeaf++;if(nodes[next].hasEscapeRoot)escapesRoot++;}if(node.isPrisoner){// if root is PRISONER,node.hasEscapeLeaf=false;// then it must not have escape paths to leafnode.hasEscapeRoot=true;// but it can escape to rootres+=escapesLeaf;// set guards on those leaves}else{// if root is NOT PRISONER, if(escapesLeaf==n){// all subtrees has escape to leaf// it a empty subtree, do nothing}elseif(escapesLeaf==0){// no subtree has escape to leaf// then we do NOT need a guard herenode.hasEscapeLeaf=false;// set no escape to leafif(escapesRoot>0){// if at least one subtree has prisoner can escape to rootnode.hasEscapeRoot=true;}}else{// has SOME escape pathif(escapesRoot==0){// if no prisoner can escape to root// then we do NOT need a guard herenode.hasEscapeLeaf=true;// because it has escape pathsnode.hasEscapeRoot=false;// obviously}else{// if some prisoner can escape to rootres++;// set guard here, prevent them escape to leaves through this nodenode.hasEscapeLeaf=false;// we set the guard, so there is no escape path to leavesnode.hasEscapeRoot=false;// as above}}}}booleanisLeaf(Nodenode){if(node.tlist.size()==1)returntrue;elsereturnfalse;}classNode{intparentIndex;booleanisPrisoner=false;booleanhasEscapeLeaf=true;booleanhasEscapeRoot=false;List<Integer>tlist=newArrayList<Integer>();}