public void Reversal()
 {
     Vertex1.ConnectionVertices.Remove(Vertex2);
     Vertex2.ConnectionVertices.Add(Vertex1);
     Vertex _Temp = Vertex1;
     Vertex1 = Vertex2;
     Vertex2 = _Temp;
 }
 /// <summary>
 /// Khởi tạo từ 2 đỉnh
 /// </summary>
 /// <param name="_Vertex1">Đỉnh 1</param>
 /// <param name="_Vertex2">Đỉnh 2</param>
 public Edge(Vertex _Vertex1, Vertex _Vertex2)
 {
     Vertex1 = _Vertex1;
     Vertex2 = _Vertex2;
     UseDefaultValue();
 }
        /// <summary>
        /// Thêm đỉnh
        /// </summary>
        /// <param name="isHaveLocation">Có biết vị trí đỉnh cần thêm chưa?</param>
        public void RunAddVertex(bool isHaveLocation)
        {
            try
            {
                if (Vertices.Count == 0)
                {
                    bool Checker;
                    do
                    {
                        Checker = true;
                        int aNumber = InputNumber("Bạn cần tạo loại đồ thị gì?\n\t1. Có hướng\n\t2. Vô hướng", "Loại đồ thị", false);
                        if (aNumber == 1)
                            IsDirected = true;
                        else if (aNumber == 2)
                            IsDirected = false;
                        else
                        {
                            MessageBox.Show("Nhập số tương ứng để chọn câu trả lời! Đề nghị nhập lại một trong 2 số 1 và 2.", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            Checker = false;
                        }
                    } while (!Checker);

                }
                int NewVertexValue = InputVertex("Nhập giá trị của đỉnh:", "Thêm đỉnh mới [1/3]", true);
                Vertex _Vtemp;
                if (isHaveLocation)
                {
                    _Vtemp = new Vertex(MenuLocation, NewVertexValue);
                }
                else
                {
                    _Vtemp = new Vertex(NewVertexValue);
                    _Vtemp.UseDefaultRectangle(Vertices.Count, ControlerForm.ClientSize.Width, ControlerForm.ClientSize.Height);
                }
                bool aChecker;
                int NumberOfVertexConnected;
                do
                {
                    aChecker = true;
                    NumberOfVertexConnected = InputNumber("Nhập số lượng đỉnh có kết nối với đỉnh này:", "Thêm đỉnh mới [2/3]", false);
                    if (NumberOfVertexConnected > Vertices.Count)
                    {
                        MessageBox.Show("Đồ thị hiện tại có " + Vertices.Count + " đỉnh. Đề nghị nhập lại!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        aChecker = false;
                    }

                } while (!aChecker);
                for (int i = 0; i < NumberOfVertexConnected; i++)
                {
                    int ConnectedVertexValue = InputVertex("Cạnh thứ " + (i + 1).ToString() + " nối từ đỉnh " + NewVertexValue + " tới đỉnh: ", "Thêm đỉnh mới [2." + (i + 1).ToString() + "a/2]", false);
                    Vertex ConnectedVertex = GetVertex(ConnectedVertexValue);
                    int EdgeWeight = InputNumber("Cạnh vừa tạo có giá trị: ", "Thêm đỉnh mới [2." + (i + 1).ToString() + "b/2]", true);
                    if (IsDirected)
                    {
                        bool Checker;
                        do
                        {
                            Checker = true;
                            int aNumber = InputNumber("Chọn hướng của cạnh vừa tạo?\n\t1. Có hướng từ đỉnh " + _Vtemp.Value + " tới đỉnh " + ConnectedVertex.Value + "\n\t2. Có hướng từ đỉnh " + ConnectedVertex.Value + " tới đỉnh " + _Vtemp.Value, "Thêm đỉnh mới [2." + (i + 1).ToString() + "c/2]", false);
                            if (aNumber == 1)
                                AddConection(_Vtemp, ConnectedVertex, EdgeWeight);
                            else if (aNumber == 2)
                                AddConection(ConnectedVertex ,_Vtemp, EdgeWeight);
                            else
                            {
                                MessageBox.Show("Nhập số tương ứng để chọn câu trả lời! Đề nghị nhập lại một trong 2 số 1 và 2.", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                Checker = false;
                            }
                        } while (!Checker);
                    }
                    else
                        AddConection(_Vtemp, ConnectedVertex, EdgeWeight);
                }
                Vertices.Add(_Vtemp);
                ControlerForm.Invalidate();
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message + " Sẽ không có đỉnh nào được thêm vào", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        /// <summary>
        /// Kết nối 2 đỉnh lại với nhau / Tạo một cạnh
        /// </summary>
        /// <param name="Source">Đỉnh bắt đầu</param>
        /// <param name="Target">Đỉnh kết thúc</param>
        /// <param name="EdgeWeight">Trọng số</param>
        private void AddConection(Vertex Source, Vertex Target, int EdgeWeight)
        {
            if (!Source.ConnectionVertices.Contains(Target))
            {
                Source.ConnectionVertices.Add(Target);
                if (!IsDirected)
                    Target.ConnectionVertices.Add(Source);
                Edge _Edge = new Edge(Source, Target);
                _Edge.Value = EdgeWeight;
                Edges.Add(_Edge);

            }
        }
 /// <summary>
 /// Xoá tất cả các cạnh của 1 đỉnh
 /// </summary>
 /// <param name="Source">Đỉnh cần thao tác</param>
 private void RemoveAllConections(Vertex Source)
 {
     if (IsDirected)
     {
         foreach (Vertex Target in Vertices)
         {
             if (GetEdge(Source, Target) != null)
             {
                 Edges.Remove(GetEdge(Source, Target));
             }
             if (GetEdge(Target, Source) != null)
             {
                 Target.ConnectionVertices.Remove(Source);
                 Edges.Remove(GetEdge(Target, Source));
             }
         }
     }
     else
     {
         foreach (Vertex Target in Source.ConnectionVertices)
         {
             Target.ConnectionVertices.Remove(Source);
             Edges.Remove(GetEdge(Source, Target));
             //Edges.Remove(GetEdge(Target, Source));
         }
     }
     Source.ConnectionVertices.Clear();
 }
 /// <summary>
 /// Xoá kết nối giữa 2 đỉnh / Xoá cạnh
 /// </summary>
 /// <param name="Source">Đỉnh bắt đầu</param>
 /// <param name="Target">Đỉnh kết thúc</param>
 private void RemoveConection(Vertex Source, Vertex Target)
 {
     Edges.Remove(GetEdge(Source, Target));
     Source.ConnectionVertices.Remove(Target);
     if (!IsDirected)
         Target.ConnectionVertices.Remove(Source);
 }
 //BookmarkConnectedComponents
 /// <summary>
 /// Sử dụng giải thuật Loang để đánh dấu thành phần liên thông với 1 đỉnh
 /// </summary>
 /// <param name="Source">Đỉnh bắt đầu</param>
 /// <param name="EdgeColor">Màu sẽ đánh dấu vào cạnh</param>
 private void Loang(Vertex Source, Color EdgeColor)
 {
     Source.Status = VertexStatus.sApproved;
     //foreach (Vertex Target in Source.ConnectionVertices)
     //{
     //    if (Target.Status != VertexStatus.sApproved)
     //    {
     //        Target.BorderColor = Source.BorderColor;
     //        Target.BackgroundColor = Source.BackgroundColor;
     //        Target.TextColor = Source.TextColor;
     //        GetEdge(Source, Target).Color = EdgeColor;
     //        Target.Status = VertexStatus.sConnected;
     //        Loang(Target, EdgeColor);
     //    }
     //}
     foreach (Vertex Target in Vertices)
     {
         Edge E1 = GetEdge(Source, Target);
         Edge E2 = GetEdge(Target, Source);
         if (Target.Status != VertexStatus.sApproved && (E1 != null || E2 != null))
         {
             Target.BorderColor = Source.BorderColor;
             Target.BackgroundColor = Source.BackgroundColor;
             Target.TextColor = Source.TextColor;
             if (E1 != null)
                 E1.Color = EdgeColor;
             else if (E2 != null)
                 E2.Color = EdgeColor;
             Target.Status = VertexStatus.sConnected;
             Loang(Target, EdgeColor);
         }
     }
 }
 /// <summary>
 /// Tìm cạnh nối giữa 2 đỉnh
 /// </summary>
 /// <param name="V1">Đỉnh thứ nhất</param>
 /// <param name="V2">Đỉnh thứ hai</param>
 /// <returns>Cạnh nối 2 đỉnh / null nếu ko có</returns>
 private Edge GetEdge(Vertex V1, Vertex V2)
 {
     foreach (Edge E in Edges)
     {
         if (E.Vertex1.Value == V1.Value && E.Vertex2.Value == V2.Value) return E;
         if (E.Vertex1.Value == V2.Value && E.Vertex2.Value == V1.Value && !IsDirected) return E;
     }
     return null;
 }
 /// <summary>
 /// Thêm đỉnh
 /// </summary>
 public void AddVertex()
 {
     try
     {
         int NewVertexValue = InputVertex("Nhập giá trị của đỉnh:", "Thêm đỉnh mới [1/3]", true);
         Vertex _Vtemp = new Vertex(NewVertexValue);
         int NumberOfVertexConnected = InputNumber("Nhập số lượng đỉnh có kết nối với đỉnh này:", "Thêm đỉnh mới [2/3]", false);
         for (int i = 0; i < NumberOfVertexConnected; i++)
         {
             int ConnectedVertexValue = InputVertex("Cạnh thứ " + (i + 1).ToString() + " nối từ đỉnh " + NewVertexValue + " tới đỉnh: ", "Thêm đỉnh mới [2." + (i + 1).ToString() + "a/2]", false);
             Vertex ConnectedVertex = GetVertex(ConnectedVertexValue);
             int EdgeWeight = InputNumber("Cạnh vừa tạo có giá trị: ", "Thêm đỉnh mới [2." + (i + 1).ToString() + "b/2]", true);
             AddConection(ConnectedVertex, _Vtemp, EdgeWeight);
         }
         _Vtemp.UseDefaultRectangle(Vertices.Count, ControlerForm.ClientSize.Width, ControlerForm.ClientSize.Height);
         Vertices.Add(_Vtemp);
         ControlerForm.Invalidate();
     }
     catch (System.Exception ex)
     {
         MessageBox.Show(ex.Message + " Sẽ không có đỉnh nào được thêm vào", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
     }
 }
 /// <summary>
 /// Xoá tất cả các cạnh của 1 đỉnh
 /// </summary>
 /// <param name="Source">Đỉnh cần thao tác</param>
 private void RemoveAllConections(Vertex Source)
 {
     foreach (Vertex Target in Source.ConnectionVertices)
     {
         Target.ConnectionVertices.Remove(Source);
         Edges.Remove(GetEdge( Source, Target));
     }
     Source.ConnectionVertices.Clear();
 }
 //BookmarkConnectedComponents
 /// <summary>
 /// Sử dụng giải thuật Loang để đánh dấu thành phần liên thông với 1 đỉnh
 /// </summary>
 /// <param name="Source">Đỉnh bắt đầu</param>
 /// <param name="EdgeColor">Màu sẽ đánh dấu vào cạnh</param>
 private void Loang(Vertex Source, Color EdgeColor)
 {
     Source.Status = VertexStatus.sApproved;
     foreach (Vertex Target in Source.ConnectionVertices)
     {
         if (Target.Status != VertexStatus.sApproved)
         {
             Target.BorderColor = Source.BorderColor;
             Target.BackgroundColor = Source.BackgroundColor;
             Target.TextColor = Source.TextColor;
             GetEdge(Source, Target).Color = EdgeColor;
             Target.Status = VertexStatus.sConnected;
             Loang(Target, EdgeColor);
         }
     }
 }