using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace MathModEduPr02
{
    internal class Graph
    {
        List<(int, int)> edges;
        public List<(int, int)> Edges { get => edges; }
        public Graph(List<(int, int)> data)
        {
            edges = new List<(int, int)> (data);
        }
        public Graph(string preufferCode)
        {
            edges = new List<(int, int)>();
            PreufferDecoding(preufferCode.Split(' ').Select(int.Parse).ToList());
        }
        public List<int> PreufferEncoding()
        {
            List<(int,int)> curEdges = new List<(int, int)> (edges);
            List<int> PreufferCode = new List<int>();
            while(curEdges.Count != 1)
            {
                int minEl = FindMinHangingVertex(curEdges);
                var edgeIndex = curEdges.FindIndex(x=> x.Item1== minEl || x.Item2==minEl);
                PreufferCode.Add(curEdges[edgeIndex].Item1 == minEl ? curEdges[edgeIndex].Item2 : curEdges[edgeIndex].Item1);
                curEdges.RemoveAt(edgeIndex);
            }
            return PreufferCode;
        }
        int FindMinHangingVertex(List<(int,int)> curEdges)
        {
            Dictionary<int,int> countVertexes = new Dictionary<int,int>();
            foreach((int first, int second) in curEdges)
            {
                _ = countVertexes.ContainsKey(first) == true ? ++countVertexes[first] : countVertexes[first] = 1;
                _ = countVertexes.ContainsKey(second) == true ? ++countVertexes[second] : countVertexes[second] = 1;
            }
            return countVertexes.Where(x => x.Value == 1).OrderBy(x => x.Key).First().Key;
        }
        void PreufferDecoding(List<int> code)
        {
            List<int> vertexes = Enumerable.Range(1, code.Count + 2).ToList();
            while (code.Count > 0)
            {
                int minVertex = vertexes.Where(x => !code.Contains(x)).Min();
                edges.Add((code.First(), minVertex));
                code.RemoveAt(0);
                vertexes.Remove(minVertex);
            }
            edges.Add((vertexes[0], vertexes[1]));
        }
    }
}
