OLLI_BS

Eyler/Hamilton

Jun 1st, 2017
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 13.42 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.IO;
  4.  
  5. public class Graph
  6. {
  7.  
  8.     public class Queue
  9.     {
  10.         private class Node //вложенный класс, реализующий базовый элемент очереди
  11.         {
  12.             private object inf;
  13.             private Node next;
  14.             public Node(object nodeInfo)
  15.             {
  16.                 inf = nodeInfo;
  17.                 next = null;
  18.             }
  19.             public Node Next
  20.             {
  21.                 get { return next; }
  22.                 set { next = value; }
  23.             }
  24.             public object Inf
  25.             {
  26.                 get { return inf; }
  27.                 set { inf = value; }
  28.             }
  29.         } //конец класса Node
  30.         private Node head;
  31.         private Node tail;
  32.         public Queue()
  33.         {
  34.             head = null;
  35.             tail = null;
  36.         }
  37.         public void Add(object nodeInfo)
  38.         {
  39.             Node r = new Node(nodeInfo);
  40.             if (head == null)
  41.             {
  42.                 head = r;
  43.                 tail = r;
  44.             }
  45.             else
  46.             {
  47.                 tail.Next = r;
  48.                 tail = r;
  49.             }
  50.         }
  51.         public object Take()
  52.         {
  53.             if (head == null)
  54.             {
  55.                 throw new Exception("Очередь пуста.");
  56.             }
  57.             else
  58.             {
  59.                 Node r = head;
  60.                 head = head.Next;
  61.  
  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.  
  85.     private class Node //вложенный класс для скрытия данных и алгоритмов
  86.     {
  87.         private int[,] array; //матрица смежности
  88.         public int this[int i, int j] //индексатор для обращения к матрице смежности
  89.         {
  90.             get
  91.             {
  92.                 return array[i, j];
  93.             }
  94.             set
  95.             {
  96.                 array[i, j] = value;
  97.             }
  98.         }
  99.         public int Size //свойство для получения размерности матрицы смежности
  100.         {
  101.             get
  102.             {
  103.                 return array.GetLength(0);
  104.             }
  105.         }
  106.         private bool[] nov; //вспомогательный массив: если i-ый элемент массива равен
  107.         //true, то i-ая вершина еще не просмотрена; если i-ый
  108.         //элемент равен false, то i-ая вершина просмотрена
  109.         public void NovSet() //метод помечает все вершины графа как непросмотреные
  110.         {
  111.             for (int i = 0; i < Size; i++)
  112.             {
  113.                 nov[i] = true;
  114.             }
  115.         }
  116.         public bool NovGet(int i) //метод помечает все вершины графа как непросмотреные
  117.         {
  118.  
  119.             return nov[i];
  120.  
  121.         }
  122.         //конструктор вложенного класса, инициализирует матрицу смежности и
  123.         // вспомогательный массив
  124.         public Node(int[,] a)
  125.         {
  126.             array = a;
  127.             nov = new bool[a.GetLength(0)];
  128.         }
  129.         //реализация алгоритма обхода графа в глубину
  130.  
  131.         public void Dfs(int v)
  132.         {
  133.             Console.Write("{0} ", v); //просматриваем текущую вершину
  134.             nov[v] = false; //помечаем ее как просмотренную
  135.             // в матрице смежности просматриваем строку с номером v
  136.             for (int u = 0; u < Size; u++)
  137.             {
  138.                 //если вершины v и u смежные, к тому же вершина u не просмотрена,
  139.                 if (array[v, u] != 0 && nov[u])
  140.                 {
  141.                     Dfs(u); // то рекурсивно просматриваем вершину
  142.                 }
  143.             }
  144.         }
  145.         //реализация алгоритма Флойда
  146.         public long[,] Floyd(out int[,] p)
  147.         {
  148.             int i, j, k;
  149.             //создаем массивы р и а
  150.             long[,] a = new long[Size, Size];
  151.             p = new int[Size, Size];
  152.             for (i = 0; i < Size; i++)
  153.             {
  154.                 for (j = 0; j < Size; j++)
  155.                 {
  156.                     if (i == j)
  157.                     {
  158.                         a[i, j] = 0;
  159.                     }
  160.                     else
  161.                     {
  162.                         if (array[i, j] == 0)
  163.                         {
  164.                             a[i, j] = int.MaxValue;
  165.                         }
  166.                         else
  167.                         {
  168.                             a[i, j] = array[i, j];
  169.                         }
  170.                     }
  171.                     p[i, j] = -1;
  172.                 }
  173.             }
  174.             //осуществляем поиск кратчайших путей
  175.             for (k = 0; k < Size; k++)
  176.             {
  177.                 for (i = 0; i < Size; i++)
  178.                 {
  179.                     for (j = 0; j < Size; j++)
  180.                     {
  181.                         long distance = a[i, k] + a[k, j];
  182.                         if (a[i, j] > distance)
  183.                         {
  184.                             a[i, j] = distance;
  185.                             p[i, j] = k;
  186.                         }
  187.                     }
  188.                 }
  189.             }
  190.             return a;//в качестве результата возвращаем массив кратчайших путей между
  191.         } //всеми парами вершин
  192.  
  193.         //восстановление пути от вершины a до вершины в для алгоритма Флойда
  194.         public void WayFloyd(int a, int b, int[,] p, ref Queue items)
  195.         {
  196.             int k = p[a, b];
  197.             //если k<> -1, то путь состоит более чем из двух вершин а и b, и проходит через
  198.             //вершину k, поэтому
  199.             if (k != -1)
  200.             {
  201.                 // рекурсивно восстанавливаем путь между вершинами а и k
  202.                 WayFloyd(a, k, p, ref items);
  203.                 items.Add(k); //помещаем вершину к в очередь
  204.                 // рекурсивно восстанавливаем путь между вершинами k и b
  205.                 WayFloyd(k, b, p, ref items);
  206.             }
  207.         }
  208.  
  209.         public void Reach(int v)
  210.         {
  211.             nov[v] = false;
  212.             for (int u = 0; u < Size; u++)
  213.             {
  214.                 if
  215.                 (array[v, u] != 0 && nov[u])
  216.                 {
  217.                     Reach(u);
  218.                 }
  219.             }
  220.         }
  221.  
  222.         public void SearchG(int v, ref int[,] a, ref Stack c) //во вложенном классе
  223.         {
  224.             for (int i = 0; i < a.GetLength(0); i++)
  225.             {
  226.                 if (a[v, i] != 0)
  227.                 {
  228.                     a[v, i] = 0; a[i, v] = 0;
  229.                     SearchG(i, ref a, ref c);
  230.                 }
  231.             }
  232.             c.Push(v);
  233.         }
  234.  
  235.         public void SearchGm(int k, ref int[] St) //вложенный класс
  236.         {
  237.             int v = St[k - 1];
  238.             for (int j = 0; j < array.GetLength(0); j++)
  239.             {
  240.                 if (array[v, j] != 0)
  241.                 {
  242.                     if (k == array.GetLength(0) && j == 0)
  243.                     {
  244.                         St[k] = j;
  245.                         foreach (int item in St)
  246.                         {
  247.                             Console.Write("{0} ", item + 1);
  248.                         }
  249.                         Console.WriteLine();
  250.                        
  251.                     }
  252.                     else
  253.                     {
  254.                         if (nov[j])
  255.                         {
  256.                             St[k] = j;
  257.                             nov[j] = false;
  258.                             SearchGm(k + 1, ref St);
  259.                             nov[j] = true;
  260.                         }
  261.                     }
  262.                 }
  263.             }
  264.         }
  265.  
  266.         public bool this[int i] //индексатор для обращения к матрице меток
  267.         {
  268.             get
  269.             {
  270.                 return nov[i];
  271.             }
  272.             set
  273.             {
  274.                 nov[i] = value;
  275.             }
  276.         }
  277.  
  278.     } //конец вложенного клаcса
  279.  
  280.     private Node graph; //закрытое поле, реализующее АТД «граф»
  281.     public Graph(string name) //конструктор внешнего класса
  282.     {
  283.         using (StreamReader fileIn = new StreamReader("../../input.txt"))
  284.         {
  285.             int n = int.Parse(fileIn.ReadLine());
  286.             int[,] a = new int[n, n];
  287.             for (int i = 0; i < n; i++)
  288.             {
  289.                 string line = fileIn.ReadLine();
  290.                 string[] mas = line.Split(' ');
  291.                 for (int j = 0; j < n; j++)
  292.                 {
  293.                     a[i, j] = int.Parse(mas[j]);
  294.                 }
  295.             }
  296.             graph = new Node(a);
  297.         }
  298.     }
  299.  
  300.     //метод выводит матрицу смежности на консольное окно
  301.     public void Show()
  302.     {
  303.         for (int i = 0; i < graph.Size; i++)
  304.         {
  305.             for (int j = 0; j < graph.Size; j++)
  306.             {
  307.                 Console.Write("{0,4}", graph[i, j]);
  308.             }
  309.             Console.WriteLine();
  310.         }
  311.     }
  312.  
  313.     public void Dfs(int v)
  314.     {
  315.         graph.NovSet();//помечаем все вершины графа как непросмотренные
  316.         graph.Dfs(v); //запускаем алгоритм обхода графа в глубину
  317.         Console.WriteLine();
  318.     }
  319.  
  320.     public void Floyd()
  321.     {
  322.         int[,] p;
  323.         long[,] a = graph.Floyd(out p); //запускаем алгоритм Флойда
  324.         int i, j;
  325.         //анализируем полученные данные и выводим их на экран
  326.         for (i = 0; i < graph.Size; i++)
  327.         {
  328.             for (j = 0; j < graph.Size; j++)
  329.             {
  330.                 if (i != j)
  331.                 {
  332.                     if (a[i, j] == int.MaxValue)
  333.                     {
  334.                         Console.WriteLine("Пути из вершины {0} в вершину {1} не существует", i, j);
  335.                     }
  336.                     else
  337.                     {
  338.                         Console.Write("Кратчайший путь от вершины {0} до вершины {1} равен {2}, ", i, j, a[i, j]);
  339.  
  340.                         Console.Write(" путь ");
  341.                         Queue items = new Queue();
  342.                         items.Add(i);
  343.                         graph.WayFloyd(i, j, p, ref items);
  344.                         items.Add(j);
  345.                         while (!items.IsEmpty)
  346.                         {
  347.                             Console.Write("{0} ", items.Take());
  348.                         }
  349.                         Console.WriteLine();
  350.                     }
  351.                 }
  352.             }
  353.         }
  354.     }
  355.  
  356.     public void Reachable(int v)
  357.     {
  358.         graph.NovSet();
  359.         Console.Write("Вершины достижимые из {0} вершины: ", v);
  360.         graph.Reach(v);
  361.         for (int i = 0; i < graph.Size; i++)
  362.         {
  363.             if (!graph.NovGet(i) && i != v) //если вершина была просмотрена, то она достижима
  364.             {
  365.                 Console.Write("{0} ", i);
  366.             }
  367.         }
  368.         Console.WriteLine();
  369.     }
  370.  
  371.     public void SearchG() // внешний класс
  372.     {
  373.         int[,] a = new int[graph.Size, graph.Size];
  374.         for (int i = 0; i < graph.Size; i++)
  375.         {
  376.             for (int j = 0; j < graph.Size; j++)
  377.             {
  378.                 a[i, j] = graph[i, j];
  379.             }
  380.         }
  381.         Stack c = new Stack();
  382.         graph.SearchG(0, ref a, ref c);
  383.         while (c.Count != 0)
  384.         {
  385.             Console.Write("{0} ", (int)c.Pop() + 1);
  386.         }
  387.     }
  388.  
  389.     public void SearchGm()//внешний класс
  390.     {
  391.         graph.NovSet();
  392.         int[] St = new int[graph.Size + 1];
  393.         St[0] = 0;
  394.         graph[0] = false; //обращение к индексатору
  395.         graph.SearchGm(1, ref St);
  396.     }
  397.  
  398.     class Program
  399.     {
  400.         static void Main(string[] args)
  401.         {
  402.             Graph graph = new Graph("input.txt");
  403.            
  404.             graph.SearchGm();
  405.             Console.WriteLine();
  406.  
  407.             graph.SearchG();
  408.  
  409.             Console.ReadKey();
  410.         }
  411.     }
  412. }
Add Comment
Please, Sign In to add comment