ural 1242. Werewolf
1242. Werewolf
Time limit: 1.0 second
Memory limit: 64 MB
Memory limit: 64 MB
Knife. Moonlit night. Rotten stump with a short black-handled knife in it. Those who know will understand. Disaster in the village. Werewolf.
There are no so many residents in the village. Many of them are each other's relatives. Only this may help to find the werewolf. The werewolf is merciless, but his descendants never become his victims. The werewolf can drown the village in blood, but he never kills his ancestors.
It is known about all the villagers who is the child of whom. Also, the sad list of the werewolf's victims is known. Your program should help to determine the suspects. It would be a hard task, if a very special condition would not hold. Namely, citizens of the village are not used to leave it. If some ancestor of some citizen lives in the village, then also his immediate ancestor does. It means, that, for example, if the father of the mother of some citizen still lives in the village, than also his mother still lives.
Input
The first line contains an integer N, 1 < N ≤ 1000, which is the number of the villagers. The villagers are assigned numbers from 1 to N. Further is the description of the relation "child-parent": a sequence of lines, each of which contains two numbers separated with a space; the first number in each line is the number of a child and the second number is the number of the child's parent. The data is correct: for each of the residents there are no more than two parents, and there are no cycles. The list is followed by the word "BLOOD" written with capital letters in a separate line. After this word there is the list of the werewolf's victims, one number in each line.
Output
The output should contain the numbers of the residents who may be the werewolf. The numbers must be in the ascending order and separated with a space. If there are no suspects, the output should contain the only number 0.
Samples
input | output |
---|---|
8 1 3 3 6 4 5 6 2 4 6 8 1 BLOOD 3 8 |
4 5 7 |
6 1 2 3 2 1 4 3 4 2 6 5 2 5 4 BLOOD 2 5 |
0 |
Problem Author: Leonid Volkov
Problem Source: Ural State University Personal Programming Contest, March 1, 2003
Problem Source: Ural State University Personal Programming Contest, March 1, 2003
Tags: graph theory
Difficulty: 232
题意:有一个村庄,里面居住着n个村民, 其中有一个狼人n<=1000。现在有一些人死了。狼人不会杀自己祖先和后代。问有可能是狼人的编号。
分析:显然是很多棵树。有一个人被杀,那么从他以上的祖先和从他以下的后代都没有可能是狼人。
整个过程用递归做。
注意如果有一个点已经被标记,那么下次就不用递归找了,因为过程是一样的。
View Code
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <iostream> 9 #include <algorithm> 10 #include <map> 11 #include <set> 12 #include <ctime> 13 #include <iomanip> 14 using namespace std; 15 typedef long long LL; 16 typedef double DB; 17 #define For(i, s, t) for(int i = (s); i <= (t); i++) 18 #define Ford(i, s, t) for(int i = (s); i >= (t); i--) 19 #define Rep(i, t) for(int i = (0); i < (t); i++) 20 #define Repn(i, t) for(int i = ((t)-1); i >= (0); i--) 21 #define rep(i, x, t) for(int i = (x); i < (t); i++) 22 #define MIT (2147483647) 23 #define INF (1000000001) 24 #define MLL (1000000000000000001LL) 25 #define sz(x) ((int) (x).size()) 26 #define clr(x, y) memset(x, y, sizeof(x)) 27 #define puf push_front 28 #define pub push_back 29 #define pof pop_front 30 #define pob pop_back 31 #define ft first 32 #define sd second 33 #define mk make_pair 34 inline void SetIO(string Name) 35 { 36 string Input = Name+".in", 37 Output = Name+".out"; 38 freopen(Input.c_str(), "r", stdin), 39 freopen(Output.c_str(), "w", stdout); 40 } 41 42 inline bool Getint(int &Ret) 43 { 44 Ret = 0; 45 char Ch = ' '; 46 bool Flag = 0; 47 while(!(Ch >= '0' && Ch <= '9')) 48 { 49 if(Ch == 'B') Flag = 1; 50 if(Flag == 1 && Ch == 'D') break; 51 Ch = getchar(); 52 } 53 if(Flag) return 0; 54 while(Ch >= '0' && Ch <= '9') 55 { 56 Ret = Ret * 10 + Ch - '0'; 57 Ch = getchar(); 58 } 59 return 1; 60 } 61 62 const int N = 1010; 63 int n; 64 vector<int> Parent[N], Child[N], Ans; 65 bool Visit[N]; 66 67 inline void Input() 68 { 69 scanf("%d", &n); 70 int x, y; 71 while(Getint(x)) 72 { 73 Getint(y); 74 Parent[x].pub(y), Child[y].pub(x); 75 } 76 } 77 78 inline void GoUp(int x) 79 { 80 Visit[x] = 1; 81 int Length = sz(Parent[x]); 82 Rep(i, Length) GoUp(Parent[x][i]); 83 Parent[x].clear(); 84 } 85 86 inline void GoDown(int x) 87 { 88 Visit[x] = 1; 89 int Length = sz(Child[x]); 90 Rep(i, Length) GoDown(Child[x][i]); 91 Child[x].clear(); 92 } 93 94 inline void Solve() 95 { 96 int x; 97 while(~scanf("%d", &x)) 98 { 99 GoUp(x); 100 GoDown(x); 101 } 102 103 For(i, 1, n) 104 if(!Visit[i]) Ans.pub(i); 105 if(sz(Ans)) 106 { 107 Rep(i, sz(Ans)-1) printf("%d ", Ans[i]); 108 printf("%d\n", Ans.back()); 109 } 110 else puts("0"); 111 } 112 113 int main() 114 { 115 #ifndef ONLINE_JUDGE 116 SetIO("A"); 117 #endif 118 Input(); 119 Solve(); 120 return 0; 121 }