AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC075-C Bridge
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "Input1";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("7 7");
WillReturn.Add("1 3");
WillReturn.Add("2 7");
WillReturn.Add("3 4");
WillReturn.Add("4 5");
WillReturn.Add("4 6");
WillReturn.Add("5 6");
WillReturn.Add("6 7");
//4
}
else if (InputPattern == "Input2") {
WillReturn.Add("3 3");
WillReturn.Add("1 2");
WillReturn.Add("1 3");
WillReturn.Add("2 3");
//0
//橋である辺が存在しない場合もあります
}
else if (InputPattern == "Input3") {
WillReturn.Add("6 5");
WillReturn.Add("1 2");
WillReturn.Add("2 3");
WillReturn.Add("3 4");
WillReturn.Add("4 5");
WillReturn.Add("5 6");
//5
//全ての辺が橋である場合もあります
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct EdgeInfo
{
internal int A;
internal int B;
}
static int N;
static List<EdgeInfo> mEdgeList = new List<EdgeInfo>();
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(X => int.Parse(X)).ToArray();
SplitAct(InputList[0]);
N = wkArr[0];
foreach (string EachStr in InputList.Skip(1)) {
SplitAct(EachStr);
EdgeInfo WillAdd;
WillAdd.A = wkArr[0];
WillAdd.B = wkArr[1];
mEdgeList.Add(WillAdd);
}
int HashiCnt = 0;
for (int I = 0; I <= mEdgeList.Count - 1; I++) {
if (IsHashi(I)) HashiCnt++;
}
Console.WriteLine(HashiCnt);
}
struct JyoutaiDef
{
internal int CurrPos;
}
// 辺の添字を指定して、橋かを判定
static bool IsHashi(int pSoeji)
{
var Stk = new Stack<JyoutaiDef>();
JyoutaiDef WillPush;
WillPush.CurrPos = 1;
var VisitedSet = new HashSet<int>();
VisitedSet.Add(1);
Stk.Push(WillPush);
while (Stk.Count > 0) {
JyoutaiDef Popped = Stk.Pop();
Action<int> PushSyori = pToInd =>
{
if (VisitedSet.Add(pToInd) == false) return;
WillPush.CurrPos = pToInd;
Stk.Push(WillPush);
};
for (int I = 0; I <= mEdgeList.Count - 1; I++) {
if (I == pSoeji) continue;
EdgeInfo CurrEdge = mEdgeList[I];
if (CurrEdge.A == Popped.CurrPos) PushSyori(CurrEdge.B);
if (CurrEdge.B == Popped.CurrPos) PushSyori(CurrEdge.A);
}
}
return VisitedSet.Count < N;
}
}
解説
全ての辺に対して、
深さ優先探索で橋かを判定してます。