AtCoderのPAST
次のPASTの問題へ
前のPASTの問題へ
第1回PAST K 巨大企業
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("7");
WillReturn.Add("-1");
WillReturn.Add("1");
WillReturn.Add("1");
WillReturn.Add("2");
WillReturn.Add("2");
WillReturn.Add("3");
WillReturn.Add("3");
WillReturn.Add("6");
WillReturn.Add("7 1");
WillReturn.Add("4 1");
WillReturn.Add("2 3");
WillReturn.Add("5 1");
WillReturn.Add("5 2");
WillReturn.Add("2 5");
//Yes
//Yes
//No
//Yes
//Yes
//No
}
else if (InputPattern == "Input2") {
WillReturn.Add("20");
WillReturn.Add("4");
WillReturn.Add("11");
WillReturn.Add("12");
WillReturn.Add("-1");
WillReturn.Add("1");
WillReturn.Add("13");
WillReturn.Add("13");
WillReturn.Add("4");
WillReturn.Add("6");
WillReturn.Add("20");
WillReturn.Add("1");
WillReturn.Add("1");
WillReturn.Add("20");
WillReturn.Add("10");
WillReturn.Add("8");
WillReturn.Add("8");
WillReturn.Add("20");
WillReturn.Add("10");
WillReturn.Add("18");
WillReturn.Add("1");
WillReturn.Add("20");
WillReturn.Add("18 14");
WillReturn.Add("11 3");
WillReturn.Add("2 13");
WillReturn.Add("13 11");
WillReturn.Add("10 15");
WillReturn.Add("9 5");
WillReturn.Add("17 11");
WillReturn.Add("18 10");
WillReturn.Add("1 16");
WillReturn.Add("9 4");
WillReturn.Add("19 6");
WillReturn.Add("5 10");
WillReturn.Add("17 8");
WillReturn.Add("15 8");
WillReturn.Add("5 16");
WillReturn.Add("6 20");
WillReturn.Add("3 19");
WillReturn.Add("10 12");
WillReturn.Add("5 13");
WillReturn.Add("18 1");
//No
//No
//No
//No
//No
//No
//No
//Yes
//No
//Yes
//No
//No
//No
//Yes
//No
//Yes
//No
//No
//No
//Yes
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
// 隣接リスト
static Dictionary<int, List<int>> mToNodeListDict = new Dictionary<int, List<int>>();
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => int.Parse(pX)).ToArray();
int N = int.Parse(InputList[0]);
int RootNode = -1;
for (int I = 1; I <= N; I++) {
int FromNode = int.Parse(InputList[I]);
if (FromNode == -1) {
RootNode = I;
}
else {
if (mToNodeListDict.ContainsKey(FromNode) == false) {
mToNodeListDict[FromNode] = new List<int>();
}
mToNodeListDict[FromNode].Add(I);
}
}
// DFSを行う
DFS(RootNode);
// mDFSNumList.ForEach(pX => Console.WriteLine(pX));
// 部分木の開始Indと終了Ind[ノードID] な Dict
var PartTreeInfoDict = new Dictionary<int, PartTreeInfoDef>();
for (int I = 0; I <= mDFSNumList.Count - 1; I++) {
int CurrNum = mDFSNumList[I];
if (PartTreeInfoDict.ContainsKey(CurrNum) == false) {
PartTreeInfoDict[CurrNum] = new PartTreeInfoDef();
PartTreeInfoDict[CurrNum].StaInd = I;
}
else {
PartTreeInfoDict[CurrNum].EndInd = I;
}
}
// クエリに回答する
foreach (string EachStr in InputList.Skip(1 + N + 1)) {
SplitAct(EachStr);
int a = wkArr[0];
int b = wkArr[1];
// aがbの部下かを判定するので、bの部分木の範囲にaが含まれるかを判定
int aStaInd = PartTreeInfoDict[a].StaInd;
int bStaInd = PartTreeInfoDict[b].StaInd;
int bEndInd = PartTreeInfoDict[b].EndInd;
if (bStaInd < aStaInd && aStaInd < bEndInd) {
Console.WriteLine("Yes");
}
else {
Console.WriteLine("No");
}
}
}
// DFSを行い、下記の2通りのタイミングでノードをAddする
// 1 最初の訪問時
// 2 子ノードを全部訪問時
static List<int> mDFSNumList = new List<int>();
static void DFS(int pCurrNode)
{
mDFSNumList.Add(pCurrNode);
if (mToNodeListDict.ContainsKey(pCurrNode)) {
foreach (int EachToNode in mToNodeListDict[pCurrNode]) {
DFS(EachToNode);
}
}
mDFSNumList.Add(pCurrNode);
}
// 部分木の開始と終了を管理
class PartTreeInfoDef
{
internal int StaInd;
internal int EndInd;
}
}
解説
DFSで、部分木を求めてます。