queen parsing

C. Queen
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given a rooted tree with vertices numerated from 1 to n. A tree is a connected graph without cycles. A rooted tree has a special vertex named root.

Ancestors of the vertex i are all vertices on the path from the root to the vertex i, except the vertex i itself. The parent of the vertex i is the nearest to the vertex i ancestor of i. Each vertex is a child of its parent. In the given tree the parent of the vertex i is the vertex pi. For the root, the value pi is −1.

An example of a tree with n=8, the root is vertex 5. The parent of the vertex 2 is vertex 3, the parent of the vertex 1 is vertex 5. The ancestors of the vertex 6 are vertices 4 and 5, the ancestors of the vertex 7 are vertices 8, 3 and 5
You noticed that some vertices do not respect others. In particular, if ci=1, then the vertex i does not respect any of its ancestors, and if ci=0, it respects all of them.

You decided to delete vertices from the tree one by one. On each step you select such a non-root vertex that it does not respect its parent and none of its children respects it. If there are several such vertices, you select the one with the smallest number. When you delete this vertex v, all children of v become connected with the parent of v.

An example of deletion of the vertex 7.
Once there are no vertices matching the criteria for deletion, you stop the process. Print the order in which you will delete the vertices. Note that this order is unique.

Input
The first line contains a single integer n (1≤n≤105) — the number of vertices in the tree.

The next n lines describe the tree: the i-th line contains two integers pi and ci (1≤pi≤n, 0≤ci≤1), where pi is the parent of the vertex i, and ci=0, if the vertex i respects its parents, and ci=1, if the vertex i does not respect any of its parents. The root of the tree has −1 instead of the parent index, also, ci=0 for the root. It is guaranteed that the values pi define a rooted tree with n vertices.

Output
In case there is at least one vertex to delete, print the only line containing the indices of the vertices you will delete in the order you delete them. Otherwise print a single integer −1.

Examples
inputCopy
5
3 1
1 1
-1 0
2 1
3 0
outputCopy
1 2 4
inputCopy
5
-1 0
1 1
1 1
2 0
3 0
outputCopy
-1
inputCopy
8
2 1
-1 0
1 0
1 1
1 1
4 0
5 1
7 0
outputCopy
5
Note
The deletion process in the first example is as follows (see the picture below, the vertices with ci=1 are in yellow):

first you will delete the vertex 1, because it does not respect ancestors and all its children (the vertex 2) do not respect it, and 1 is the smallest index among such vertices;
the vertex 2 will be connected with the vertex 3 after deletion;
then you will delete the vertex 2, because it does not respect ancestors and all its children (the only vertex 4) do not respect it;
the vertex 4 will be connected with the vertex 3;
then you will delete the vertex 4, because it does not respect ancestors and all its children (there are none) do not respect it (vacuous truth);
you will just delete the vertex 4;
there are no more vertices to delete.

In the second example you don’t need to delete any vertex:

vertices 2 and 3 have children that respect them;
vertices 4 and 5 respect ancestors.

In the third example the tree will change this way:
Inspiration: Ehrlich's table
, analyze the problem, and make a "hole" while losing

#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<inttypes.h>

typedef int32_t i32;
typedef int64_t i64;

static void print_int(i64 n){
    
    
	if(n<0){
    
    
		putchar('-');
		n=-n;
	}
	if(n==0){
    
    
		putchar('0');
		return;
	}
	int s[20],len=0;
	while(n>0){
    
    
		s[len++]=n%10+'0';
		n/=10;
	}
	while(len>0){
    
    
		putchar(s[--len]);
	}
}
static i64 read_int(void){
    
    
	int prev='\0';
	int c=getchar();
	while(!('0'<=c && c<='9')){
    
    
		prev=c;
		c=getchar();
	}
	i64 res=0;
	while('0'<=c && c<='9'){
    
    
		res=10*res+c-'0';
		c=getchar();//吃掉空格,换行并借此退出 
	}
	return prev=='-'?-res:res;
}
void run (void) {
    
    
  const i32 n = read_int();//读入总数为n 
  i32 *p = (i32 *) calloc (n + 1, sizeof (i32));
  i32 *c = (i32 *) calloc (n + 1, sizeof (i32));
  i32 *cond = (i32 *) calloc (n + 1, sizeof (i32));
  for (i32 i = 1; i <= n; ++i) {
    
    
    cond[i] = 1;
  }
  for (i32 i = 1; i <= n; ++i) {
    
    
    p[i] = read_int();//只读双亲序号 
    c[i] = read_int();//只读特性 标记为0,不删除其 
    if (p[i] != -1 && c[i] == 0) {
    
    //其不是根节点且特性respect 
      cond[p[i]] = 0;// 其双亲的标记为0,不可能删除
	  //最后若一个节点又是c标记为1,又是cond里标记是1,则删除
	  //亮点:cond充当了记录器的作用,根本不需要再回头看,边输入边记录 
    }
  }
  i32 cnt = 0;
  for (i32 i = 1; i <= n; ++i) {
    
    
    if (c[i] == 1 && cond[i] == 1) {
    
    
      if (cnt > 0) {
    
    
	putchar(' ');
      }
      print_int (i);
      cnt++;
    }
  }
  if (cnt == 0) {
    
    
    print_int (-1);
  }
  putchar('\n');
}

int main (void) {
    
    
  run ();
  return 0;
}

Guess you like

Origin blog.csdn.net/qq_51945248/article/details/113730336