Advertisement
OLLI_BS

Eyler

Jun 1st, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.80 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.     } //конец вложенного клаcса
  236.  
  237.  
  238.  
  239.     private Node graph; //закрытое поле, реализующее АТД «граф»
  240.     public Graph(string name) //конструктор внешнего класса
  241.     {
  242.         using (StreamReader fileIn = new StreamReader("../../input.txt"))
  243.         {
  244.             int n = int.Parse(fileIn.ReadLine());
  245.             int[,] a = new int[n, n];
  246.             for (int i = 0; i < n; i++)
  247.             {
  248.                 string line = fileIn.ReadLine();
  249.                 string[] mas = line.Split(' ');
  250.                 for (int j = 0; j < n; j++)
  251.                 {
  252.                     a[i, j] = int.Parse(mas[j]);
  253.                 }
  254.             }
  255.             graph = new Node(a);
  256.         }
  257.     }
  258.  
  259.     //метод выводит матрицу смежности на консольное окно
  260.     public void Show()
  261.     {
  262.         for (int i = 0; i < graph.Size; i++)
  263.         {
  264.             for (int j = 0; j < graph.Size; j++)
  265.             {
  266.                 Console.Write("{0,4}", graph[i, j]);
  267.             }
  268.             Console.WriteLine();
  269.         }
  270.     }
  271.     public void Dfs(int v)
  272.     {
  273.         graph.NovSet();//помечаем все вершины графа как непросмотренные
  274.         graph.Dfs(v); //запускаем алгоритм обхода графа в глубину
  275.         Console.WriteLine();
  276.     }
  277.     public void Floyd()
  278.     {
  279.         int[,] p;
  280.         long[,] a = graph.Floyd(out p); //запускаем алгоритм Флойда
  281.         int i, j;
  282.         //анализируем полученные данные и выводим их на экран
  283.         for (i = 0; i < graph.Size; i++)
  284.         {
  285.             for (j = 0; j < graph.Size; j++)
  286.             {
  287.                 if (i != j)
  288.                 {
  289.                     if (a[i, j] == int.MaxValue)
  290.                     {
  291.                         Console.WriteLine("Пути из вершины {0} в вершину {1} не существует", i, j);
  292.                     }
  293.                     else
  294.                     {
  295.                         Console.Write("Кратчайший путь от вершины {0} до вершины {1} равен {2}, ", i, j, a[i, j]);
  296.  
  297.                         Console.Write(" путь ");
  298.                         Queue items = new Queue();
  299.                         items.Add(i);
  300.                         graph.WayFloyd(i, j, p, ref items);
  301.                         items.Add(j);
  302.                         while (!items.IsEmpty)
  303.                         {
  304.                             Console.Write("{0} ", items.Take());
  305.                         }
  306.                         Console.WriteLine();
  307.                     }
  308.                 }
  309.             }
  310.         }
  311.     }
  312.     public void Reachable(int v)
  313.     {
  314.         graph.NovSet();
  315.         Console.Write("Вершины достижимые из {0} вершины: ", v);
  316.         graph.Reach(v);
  317.         for (int i = 0; i < graph.Size; i++)
  318.         {
  319.             if (!graph.NovGet(i) && i != v) //если вершина была просмотрена, то она достижима
  320.             {
  321.                 Console.Write("{0} ", i);
  322.             }
  323.         }
  324.         Console.WriteLine();
  325.     }
  326.  
  327.     public void SearchG() //во внешнем классе
  328.     {
  329.         int[,] a = new int[graph.Size, graph.Size];
  330.         for (int i = 0; i < graph.Size; i++)
  331.         {
  332.             for (int j = 0; j < graph.Size; j++)
  333.             {
  334.                 a[i, j] = graph[i, j];
  335.             }
  336.         }
  337.         Stack c = new Stack();
  338.         graph.SearchG(0, ref a, ref c);
  339.         while (c.Count != 0)
  340.         {
  341.             Console.Write("{0} ", (int)c.Pop() + 1);
  342.         }
  343.     }
  344.  
  345.     class Program
  346.     {
  347.         static void Main(string[] args)
  348.         {
  349.             Graph graph = new Graph("input.txt");
  350.             graph.SearchG();
  351.  
  352.             Console.ReadKey();
  353.         }
  354.     }
  355. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement