题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1242
题意描述:狼人的故事,村庄里隐藏着狼人,狼人跟人是有血缘关系的;已知狼人不会杀死自己的直系亲属(及向上追溯非旁支的所有直系亲属,递归定义),也不会杀死自己的后代;现在给定人数N以及他们的子代关系,请找出里面可能是狼人的编号(1<=k[i]<=N);
思路大致就是,用一部分有向连通域和有向DFS,剩下suspect仍为true的就是嫌疑狼X!
AC代码:
//#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <map>
using namespace std;
struct Node{
vector<int>par;
vector<int>son;
bool suspect;
Node() :suspect(true){}
};
vector<Node>v;
void mark_up(int n){
v[n].suspect = false;
for (int k : v[n].par)
mark_up(k);
}
void mark_down(int n){
v[n].suspect = false;
for (int k : v[n].son)
mark_down(k);
}
void mark(int n){
mark_down(n);
mark_up(n);
}
void func(){
int n;
cin >> n;
v.resize(n + 1);
string delta;
int src, tar;
while (cin >> delta&&delta != "BLOOD"){
src = atoi(delta.c_str());
cin >> tar;
v[src].par.push_back(tar);
v[tar].son.push_back(src);
}
while (cin >> src)
mark(src);
vector<int>ans;
for (size_t i = 1; i < v.size(); i++)
{
if (v[i].suspect)ans.push_back(i);
}
if (ans.size()){
cout << ans[0];
for (size_t i = 1; i < ans.size(); i++)
cout << ' ' << ans[i];
cout << endl;
}
else
cout << 0 << endl;
}
int main(){
//freopen("out.txt", "w", stdout);
//freopen("in.txt", "r", stdin);
func();
}