//Проверка на наличие вершины в списке
 public static bool IsConVerx(List<Vertex> Q,  Vertex v)
 {
     bool End=false;
     for (int i = 0; i < Q.Count; i++)
     {
         if (Q[i] == v) End = true;
     }
     if (End) return true;
     return false;
 }
 //Находение ребра в списке ребер по заданным вершинам
 public Edge FindEdge(Vertex v1, Vertex v2)
 {
     Edge temp=null;
     for (int j = 0; j < E.Count; j++)
     {
         if ((E[j].V1 == v1 && E[j].V2 == v2) || (E[j].V2 == v1 && E[j].V1 == v2))
         {
             temp = E[j];
         }
     }
     return temp;
 }
 public Vertex(Tags Data, double x, double y, double z)
 {
     this.x = x;
     this.y = y;
     this.z = z;
     this.Data = Data;
     t = float.MaxValue;
     p = float.MaxValue;
     prev = null;
     isin = false;
     wasMin = false;
     rad = 7;
 }
 //
 public void ChangeMarkerT2(List<Vertex> l, Vertex temp)
 {
     double w = 0;
     for (int i = 0; i < l.Count; i++)
     {
         w = (float)FindEdge(temp, l[i]).Weight;
         if (l[i].t > w)
         {
             l[i].t = (float)w;
             l[i].prev = temp;
         }
     }
 }
        public static bool CheckLine(Vertex dot1, Vertex dot2, Vertex dot3)
        {
            if (dot1.GetCoordX != dot2.GetCoordX)
            {
                double k = (double)(dot2.GetCoordY - dot1.GetCoordY) / (double)(dot2.GetCoordX - dot1.GetCoordX);

                if (dot3.GetCoordY == Math.Round((dot3.GetCoordX - dot1.GetCoordX) * k + dot1.GetCoordY)) return true;

                else return false;

            }
            else
            {

                if (dot3.GetCoordX == dot1.GetCoordX) return true;
                return false;

            }
        }
        public static bool HighCheck(Vertex dot1, Vertex dot2, Vertex dot3)
        {
            if (dot1.GetCoordX != dot2.GetCoordX)
            {
                double k = (double)(dot2.GetCoordY - dot1.GetCoordY) / (double)(dot2.GetCoordX - dot1.GetCoordX);

                if (dot3.GetCoordY == (dot3.GetCoordX - dot1.GetCoordX) * k + dot1.GetCoordY) return true;
                if (dot3.GetCoordY > (dot3.GetCoordX - dot1.GetCoordX) * k + dot1.GetCoordY)
                {
                    return true;
                }
                else return false;

            }
            else
            {
                if (dot3.GetCoordX >= dot1.GetCoordX) return true;
                return false;

            }
        }
 void ClusterizeStep(Cluster cl, Vertex v, bool firststep)
 {
     if (firststep)
     {
         for (int i = 0; i < G.E.Count; i++)
         {
             if (G.E[i].V1 == v)
             {
                 ClusterizeStep(cl, G.E[i].V2, false);
             }
             else if (G.E[i].V2 == v)
             {
                 ClusterizeStep(cl, G.E[i].V1, false);
             }
         }
     }
     else
     {
         bool exists = false;
         for (int k = 0; k < cl.Data.Count; k++)
         {
             if (v == cl.Data[k])
             {
                 exists = true;
                 break;
             }
         }
         if (!exists)
         {
             cl.Data.Add(v);
             for (int i = 0; i < G.E.Count; i++)
             {
                 if (G.E[i].V1 == v)
                 {
                     ClusterizeStep(cl, G.E[i].V2, false);
                 }
                 else if (G.E[i].V2 == v)
                 {
                     ClusterizeStep(cl, G.E[i].V1, false);
                 }
             }
         }
     }
 }
        //Добавляет вершину к ближайшему кластеру
        public void AddToClosestCluster(Vertex v)
        {
            Graph temp = new Graph(G.V);
            for (int i = 0; i < temp.V.Count; i++)
            {
                for (int j = i + 1; j < temp.V.Count; j++)
                {
                    temp.E.Add(new Edge(temp.V[i], temp.V[j]));
                }
            }

            Vertex neighbour = G.V[0];
            double shortestedgeweight = double.MaxValue;
            for(int i = 0; i < temp.E.Count; i++)
            {
                if (temp.E[i].V1 == v)
                {
                    if (temp.E[i].Weight < shortestedgeweight)
                    {
                        shortestedgeweight = temp.E[i].Weight;
                        neighbour = temp.E[i].V2;
                    }
                }
                else
                {
                    if (temp.E[i].V2 == v)
                    {
                        if (temp.E[i].Weight < shortestedgeweight)
                        {
                            shortestedgeweight = temp.E[i].Weight;
                            neighbour = temp.E[i].V1;
                        }
                    }
                }
            }
                for (int i = 0; i < C.Count; i++)
                {
                    for (int j = 0; j < C[i].Data.Count; j++)
                    {
                        if (C[i].Data[j] == neighbour)
                        {
                            C[i].Data.Add(v);
                        }
                    }
                }
        }
 public Edge(Vertex V1, Vertex V2)
 {
     this.V1 = V1;
     this.V2 = V2;
     Weight = Math.Sqrt(Math.Pow((V1.x - V2.x), 2) + Math.Pow((V1.y - V2.y), 2)/* + Math.Pow((V1.z - V2.z), 2)*/);
 }
 public static void ConnectDots(Vertex dot1, Vertex dot2, Graphics g)
 {
     g.DrawLine(new Pen(new SolidBrush(Color.Black)), dot1.GetCoordX + dot1.GetRad, dot1.GetCoordY + dot1.GetRad, dot2.GetCoordX + dot2.GetRad, dot2.GetCoordY + dot2.GetRad);
 }
 //Нахождение минимального пути между вершинами
 public void FindingMinWay(Vertex first, Vertex last)
 {
     first.t = 0;
     Vertex temp;
     List<Vertex> neighbours = new List<Vertex>();
     while (last.p == max)
     {
         temp = Mint();
         temp.p = temp.t;
         neighbours = new List<Vertex>();
         FindingNeighbours1(neighbours, temp);
         ChangeMarkerT(neighbours, temp);
     }
         temp = last;
         while (temp != first)
         {
             neighbours = new List<Vertex>();
             FindingNeighbours(neighbours, temp);
             for (int i = 0; i < neighbours.Count; i++)
             {
                 double w = FindEdge(temp, neighbours[i]).Weight;
                 if (Math.Round(temp.p-neighbours[i].p,3) == Math.Round(w,3))
                 {
                     FindEdge(temp, neighbours[i]).optimal = true;
                     temp = neighbours[i];
                     break;
                 }
             }
         }
 }
 //Формирование списка вершин в минимальном остовном дереве/графе оптимального пути
 public List<Vertex> IsConList(Vertex begin)
 {
     List<Vertex> Q = new List<Vertex>();
     Q.Remove(begin);
     Q.Insert(0, begin);
     for (int i = 0; i < V.Count; i++)
     {
         V[i].cocheck = 1;
     }
     Q[0].cocheck = 2;
     while (IsConPrior(2))
     {
         for (int i = 0; i < V.Count; i++)
         {
             if (V[i].cocheck == 2)
             {
                 List<Vertex> n = new List<Vertex>();
                 V[i].cocheck = 3;
                 Q.Add(V[i]);
                 FindingNeighbours(n, V[i]);
                 for (int j = 0; j < n.Count; j++)
                 {
                     if (n[j].cocheck == 1)
                         n[j].cocheck = 2;
                 }
             }
         }
     }
     return Q;
 }
 //Нахождение минимального остовного дерева
 public void FindMinSpanTree(Vertex first)
 {
     first.t = 0;
     Vertex temp = first;
     List<Vertex> neighbours = new List<Vertex>();
     List<Vertex> Q = new List<Vertex>();
     while (Gone())
     {
         temp = Mint();
         temp.p = temp.t;
         neighbours = new List<Vertex>();
         FindingNeighbours1(neighbours, temp);
         ChangeMarkerT2(neighbours, temp);
         Q.Add(temp);
     }
         for (int i = 1; i < Q.Count; i++)
         {
             Edge e = FindEdge(Q[i], Q[i].prev);
             e.optimal = true;
         }
 }
 //Нахождение у вершины соседей с максимальным временным приоритетом
 public void FindingNeighbours1(List<Vertex> l, Vertex temp)
 {
     for (int j = 0; j < E.Count; j++)
     {
         if (E[j].V1 == temp && E[j].V2.p==max)
         {
             l.Add(E[j].V2);
         }
         else if (E[j].V2 == temp && E[j].V1.p==max)
         {
             l.Add(E[j].V1);
         }
     }
 }