Advertisement
Infiniti_Inter

22-1

May 26th, 2020
1,048
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.36 KB | None | 0 0
  1.  
  2.  
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.IO;
  7. namespace ConsoleApp5
  8. {
  9.     public class Queue
  10.     {
  11.         private class Node //вложенный класс, реализующий базовый элемент очереди
  12.         {
  13.             private object inf;
  14.             private Node next;
  15.             public Node(object nodeInfo)
  16.             {
  17.                 inf = nodeInfo;
  18.                 next = null;
  19.             }
  20.             public Node Next
  21.             {
  22.                 get { return next; }
  23.                 set { next = value; }
  24.             }
  25.             public object Inf
  26.             {
  27.                 get { return inf; }
  28.                 set { inf = value; }
  29.             }
  30.         } //конец класса Node
  31.         private Node head;
  32.         private Node tail;
  33.         public Queue()
  34.         {
  35.             head = null;
  36.             tail = null;
  37.         }
  38.         public void Add(object nodeInfo)
  39.         {
  40.             Node r = new Node(nodeInfo);
  41.             if (head == null)
  42.             {
  43.                 head = r;
  44.                 tail = r;
  45.             }
  46.             else
  47.             {
  48.                 tail.Next = r;
  49.                 tail = r;
  50.             }
  51.         }
  52.         public object Take()
  53.         {
  54.             if (head == null)
  55.             {
  56.                 throw new Exception("Очередь пуста.");
  57.             }
  58.             else
  59.             {
  60.                 Node r = head;
  61.                 head = head.Next;
  62.                 if (head == null)
  63.                 {
  64.                     tail = null;
  65.                 }
  66.                 return r.Inf;
  67.             }
  68.         }
  69.         public bool IsEmpty
  70.         {
  71.             get
  72.             {
  73.                 if (head == null)
  74.                 {
  75.                     return true;
  76.                 }
  77.                 else
  78.                 {
  79.                     return false;
  80.                 }
  81.             }
  82.         }
  83.     }
  84.     public class Graph
  85.     {
  86.         private class Node //вложенный класс для скрытия данных и алгоритмов
  87.         {
  88.             private int[,] array; //матрица смежности
  89.             public int this[int i, int j] //индексатор для обращения к матрице смежности
  90.             {
  91.                 get
  92.                 {
  93.                     return array[i, j];
  94.                 }
  95.                 set
  96.                 {
  97.                     array[i, j] = value;
  98.                 }
  99.             }
  100.             public int Size //свойство для получения размерности матрицы смежности
  101.             {
  102.                 get
  103.                 {
  104.                     return array.GetLength(0);
  105.                 }
  106.             }
  107.             private bool[] nov; //вспомогательный массив: если i-ый элемент массива равен
  108.                                 //true, то i-ая вершина еще не просмотрена; если i-ый
  109.                                 //элемент равен false, то i-ая вершина просмотрена
  110.             public void NovSet() //метод помечает все вершины графа как непросмотреные
  111.             {
  112.                 for (int i = 0; i < Size; i++)
  113.                 {
  114.                     nov[i] = true;
  115.                 }
  116.             }
  117.             //конструктор вложенного класса, инициализирует матрицу смежности и
  118.             // вспомогательный массив
  119.             public Node(int[,] a)
  120.             {
  121.                 array = a;
  122.                 nov = new bool[a.GetLength(0)];
  123.             }
  124.             public void AddNext()
  125.             {
  126.                 int n = array.GetLength(0) + 1;
  127.                 int[,] newArray = new int[n, n];
  128.                 for (int i = 0; i < n; ++i)
  129.                     for (int j = 0; j < n; ++j)
  130.                         newArray[i, j] = (i + 1 == n || j + 1 == n ? 0 : this[i, j]);
  131.                 array = newArray;
  132.             }
  133.             public long[,] Floyd(out int[,] p)
  134.             {
  135.                 int i, j, k;
  136.                 //создаем массивы р и а
  137.                 long[,] a = new long[Size, Size];
  138.                 p = new int[Size, Size];
  139.                 for (i = 0; i < Size; i++)
  140.                 {
  141.                     for (j = 0; j < Size; j++)
  142.                     {
  143.                         if (i == j)
  144.                         {
  145.                             a[i, j] = 0;
  146.                         }
  147.                         else
  148.                         {
  149.                             if (array[i, j] == 0)
  150.                             {
  151.                                 a[i, j] = int.MaxValue;
  152.                             }
  153.                             else
  154.                             {
  155.                                 a[i, j] = array[i, j];
  156.                             }
  157.                         }
  158.                         p[i, j] = -1;
  159.                     }
  160.                 }
  161.                 //осуществляем поиск кратчайших путей
  162.                 for (k = 0; k < Size; k++)
  163.                 {
  164.                     for (i = 0; i < Size; i++)
  165.                     {
  166.                         for (j = 0; j < Size; j++)
  167.                         {
  168.                             long distance = a[i, k] + a[k, j];
  169.                             if (a[i, j] > distance)
  170.                             {
  171.                                 a[i, j] = distance;
  172.                                 p[i, j] = k;
  173.                             }
  174.                         }
  175.                     }
  176.                 }
  177.                 return a;//в качестве результата возвращаем массив кратчайших путей между
  178.             } //всеми парами вершин
  179.               //восстановление пути от вершины a до вершины в для алгоритма Флойда
  180.             public void WayFloyd(int a, int b, int[,] p, ref Queue items)
  181.             {
  182.                 int k = p[a, b];
  183.                 //если k<> -1, то путь состоит более чем из двух вершин а и b, и проходит через
  184.                 //вершину k, поэтому
  185.                 if (k != -1)
  186.                 {
  187.                     // рекурсивно восстанавливаем путь между вершинами а и k
  188.                     WayFloyd(a, k, p, ref items);
  189.                     items.Add(k); //помещаем вершину к в очередь
  190.                                   // рекурсивно восстанавливаем путь между вершинами k и b
  191.                     WayFloyd(k, b, p, ref items);
  192.                 }
  193.             }
  194.         }
  195.  
  196.         //конец вложенного клаcса
  197.  
  198.         private Node graph; //закрытое поле, реализующее АТД «граф»
  199.         public Graph(string name) //конструктор внешнего класса
  200.         {
  201.             using (StreamReader file = new StreamReader(name))
  202.             {
  203.                 int n = int.Parse(file.ReadLine());
  204.                 int[,] a = new int[n, n];
  205.                 for (int i = 0; i < n; i++)
  206.                 {
  207.                     string line = file.ReadLine();
  208.                     string[] mas =
  209.  
  210.                     line.Split(' ');
  211.                     for (int j = 0; j < n; j++)
  212.                     {
  213.                         a[i, j] = int.Parse(mas[j]);
  214.                     }
  215.                 }
  216.                 graph = new Node(a);
  217.             }
  218.         }
  219.         public void Show()
  220.         {
  221.             for (int i = 0; i < graph.Size; i++)
  222.             {
  223.                 for (int j = 0; j < graph.Size; j++)
  224.                 {
  225.                     Console.Write("{0,4}", graph[i, j]);
  226.                 }
  227.                 Console.WriteLine();
  228.             }
  229.         }
  230.         public void AddNext()
  231.         {
  232.             graph.AddNext();
  233.         }
  234.         public void Resize(string name)
  235.         {
  236.             using (StreamReader file = new StreamReader(name))
  237.             {
  238.                 int n = int.Parse(file.ReadLine());
  239.                 int[,] help = new int[n - 1, n - 1];
  240.                 for (int i = 0; i < n - 1; i++)
  241.                 {
  242.                     for (int j = 0; j < n - 1; j++)
  243.                     {
  244.                         help[i, j] = graph[i, j];
  245.                     }
  246.  
  247.                 }
  248.                 graph = new Node(help);
  249.             }
  250.         }
  251.         public void Floyd(int i, int j)
  252.         {
  253.             int[,] p;
  254.             long[,] a = graph.Floyd(out p); //запускаем алгоритм Флойда
  255.                                             //анализируем полученные данные и выводим их на экран
  256.             if (i != j)
  257.             {
  258.                 if ((a[i, j] == int.MaxValue) || (a[i, j] == -1))
  259.                 {
  260.                     Console.WriteLine("Пути из вершины {0} в вершину {1} не существует", i, j);
  261.                 }
  262.                 else
  263.                 {
  264.                     Console.Write("Кратчайший путь от вершины {0} до вершины {1} равен {2}, ", i, j, a[i, j]);
  265.                     Console.Write(" путь ");
  266.                     Queue items = new Queue();
  267.                     items.Add(i);
  268.                     graph.WayFloyd(i, j, p, ref items);
  269.                     items.Add(j);
  270.                     while (!items.IsEmpty)
  271.                     {
  272.                         Console.Write("{0} ", items.Take());
  273.                     }
  274.                     Console.WriteLine();
  275.                 }
  276.             }
  277.         }
  278.     }
  279.     class Program
  280.     {
  281.         static void Main()
  282.         {
  283.             Graph g = new Graph(@"D:\input.txt");
  284.             Console.WriteLine("Graph:");
  285.             g.Show();
  286.             Console.WriteLine("Добавить следующую вершину:");
  287.             g.AddNext();
  288.             g.Show();
  289.             Console.WriteLine("Кратчайший путь из: ");
  290.            
  291.         }
  292.     }
  293. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement