AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC302-F Merge Set
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("3 5");
WillReturn.Add("2");
WillReturn.Add("1 2");
WillReturn.Add("2");
WillReturn.Add("2 3");
WillReturn.Add("3");
WillReturn.Add("3 4 5");
//2
}
else if (InputPattern == "Input2") {
WillReturn.Add("1 2");
WillReturn.Add("2");
WillReturn.Add("1 2");
//0
}
else if (InputPattern == "Input3") {
WillReturn.Add("3 5");
WillReturn.Add("2");
WillReturn.Add("1 3");
WillReturn.Add("2");
WillReturn.Add("2 4");
WillReturn.Add("3");
WillReturn.Add("2 4 5");
//-1
}
else if (InputPattern == "Input4") {
WillReturn.Add("4 8");
WillReturn.Add("3");
WillReturn.Add("1 3 5");
WillReturn.Add("2");
WillReturn.Add("1 2");
WillReturn.Add("3");
WillReturn.Add("2 4 7");
WillReturn.Add("4");
WillReturn.Add("4 6 7 8");
//2
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static int mM;
// 隣接リスト
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();
SplitAct(InputList[0]);
mM = wkArr[1];
var NumArrList = new List<int[]>();
for (int I = 2; I <= InputList.Count - 1; I += 2) {
SplitAct(InputList[I]);
NumArrList.Add(wkArr);
}
int SuperNodeID = 1000000000; // 超頂点
for (int I = 0; I <= NumArrList.Count - 1; I++) {
SuperNodeID++;
foreach (int EachNum in NumArrList[I]) {
int FromNode = SuperNodeID;
int ToNode = EachNum;
if (mToNodeListDict.ContainsKey(FromNode) == false) {
mToNodeListDict[FromNode] = new List<int>();
}
if (mToNodeListDict.ContainsKey(ToNode) == false) {
mToNodeListDict[ToNode] = new List<int>();
}
mToNodeListDict[FromNode].Add(ToNode);
mToNodeListDict[ToNode].Add(FromNode);
}
}
int Result = ExecBFS();
Console.WriteLine((Result - 2) / 2);
}
// BFSを行い、最短距離を返す
static int ExecBFS()
{
var Que = new Queue<JyoutaiDef>();
JyoutaiDef WillEnqueue;
WillEnqueue.CurrNode = 1;
WillEnqueue.Level = 0;
Que.Enqueue(WillEnqueue);
var VisitedSet = new HashSet<int>();
while (Que.Count > 0) {
JyoutaiDef Dequeued = Que.Dequeue();
if (Dequeued.CurrNode == mM) {
return Dequeued.Level;
}
if (mToNodeListDict.ContainsKey(Dequeued.CurrNode) == false) continue;
foreach (int EachToNode in mToNodeListDict[Dequeued.CurrNode]) {
if (VisitedSet.Add(EachToNode)) {
WillEnqueue.CurrNode = EachToNode;
WillEnqueue.Level = Dequeued.Level + 1;
Que.Enqueue(WillEnqueue);
}
}
}
return -1;
}
struct JyoutaiDef
{
internal int CurrNode;
internal int Level;
}
}
解説
各数値を超頂点として作成し、
集合のノードから辺を貼り、
(ノード1からノードMまでの距離 - 2) / 2
が解になります。