Advertisement
OLLI_BS

Detours

Jun 1st, 2017
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 12.89 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.IO;
  4.  
  5. namespace Graf
  6. {
  7.     class Graph
  8.     {
  9.         private class Node //вложенный класс для скрытия данных и алгоритмов
  10.         {
  11.             private int[,] array; //матрица смежности
  12.             public int this[int i, int j] //индексатор для обращения к матрице смежности
  13.             {
  14.                 get
  15.                 {
  16.                     return array[i, j];
  17.                 }
  18.                 set
  19.                 {
  20.                     array[i, j] = value;
  21.                 }
  22.             }
  23.             public int Size //свойство для получения размерности матрицы смежности
  24.             {
  25.                 get
  26.                 {
  27.                     return array.GetLength(0);
  28.                 }
  29.             }
  30.             private bool[] nov; //вспомогательный массив: если i-ый элемент массива равен
  31.             //true, то i-ая вершина еще не просмотрена; если i-ый
  32.             //элемент равен false, то i-ая вершина просмотрена
  33.  
  34.             public void NovSet() //метод помечает все вершины графа как непросмотреные
  35.             {
  36.                 for (int i = 0; i < Size; i++)
  37.                 {
  38.                     nov[i] = true;
  39.                 }
  40.             }
  41.  
  42.             //конструктор вложенного класса, инициализирует матрицу смежности и
  43.             // вспомогательный массив
  44.             public Node(int[,] a)
  45.             {
  46.                 array = a;
  47.                 nov = new bool[a.GetLength(0)];
  48.             }
  49.  
  50.             public void Dfs(int v) //реализация алгоритма обхода графа в глубину
  51.             {
  52.                 Console.Write("{0} ", v); //просматриваем текущую вершину
  53.                 nov[v] = false; //помечаем ее как просмотренную
  54.                 // в матрице смежности просматриваем строку с номером v
  55.                 for (int u = 0; u < Size; u++)
  56.                 {
  57.                     //если вершины v и u смежные, к тому же вершина u не просмотрена,
  58.                     if (array[v, u] != 0 && nov[u])
  59.                     {
  60.                         Dfs(u); // то рекурсивно просматриваем вершину
  61.                     }
  62.                 }
  63.             }
  64.  
  65.             public bool[] Reach(int v) //выполняет обход графа в глубину для вершины v, но не выводит просмотренные вершины на экран
  66.             {
  67.                 nov[v] = false;
  68.                 for (int u = 0; u < Size; u++)
  69.                 {
  70.                     if (array[v, u] != 0 && nov[u])
  71.                     {
  72.                         Reach(u);
  73.                     }
  74.                 }
  75.                 return nov;
  76.             }
  77.  
  78.             //реализация алгоритма Дейкстры
  79.             public long[] Dijkstr(int v, out int[] p)
  80.             {
  81.                 nov[v] = false; // помечаем вершину v как просмотренную
  82.                 //создаем матрицу с
  83.                 int[,] c = new int[Size, Size];
  84.                 for (int i = 0; i < Size; i++)
  85.                 {
  86.                     for (int u = 0; u < Size; u++)
  87.                     {
  88.                         if (array[i, u] == 0 || i == u)
  89.                         {
  90.                             c[i, u] = int.MaxValue;
  91.                         }
  92.                         else
  93.                         {
  94.                             c[i, u] = array[i, u];
  95.                         }
  96.                     }
  97.                 }
  98.  
  99.                 //создаем матрицы d и p
  100.                 long[] d = new long[Size];
  101.                 p = new int[Size];
  102.                 for (int u = 0; u < Size; u++)
  103.                 {
  104.                     if (u != v)
  105.                     {
  106.                         d[u] = c[v, u];
  107.                         p[u] = v;
  108.                     }
  109.                 }
  110.                 for (int i = 0; i < Size - 1; i++) // на каждом шаге цикла
  111.                 {
  112.                     // выбираем из множества V\S такую вершину w, что D[w] минимально
  113.                     long min = int.MaxValue;
  114.                     int w = 0;
  115.                     for (int u = 0; u < Size; u++)
  116.                     {
  117.                         if (nov[u] && min > d[u])
  118.                         {
  119.                             min = d[u];
  120.                             w = u;
  121.                         }
  122.                     }
  123.                     nov[w] = false; //помещаем w в множество S
  124.                     //для каждой вершины из множества V\S определяем кратчайший путь от
  125.                     // источника до этой вершины
  126.                     for (int u = 0; u < Size; u++)
  127.                     {
  128.                         long distance = d[w] + c[w, u];
  129.                         if (nov[u] && d[u] > distance)
  130.                         {
  131.                             d[u] = distance;
  132.                             p[u] = w;
  133.                         }
  134.                     }
  135.                 }
  136.                 return d; //в качестве результата возвращаем массив кратчайших путей для заданного источника
  137.             }
  138.  
  139.             //восстановление пути от вершины a до вершины b для алгоритма Дейкстры
  140.             public void WayDijkstr(int a, int b, int[] p, ref Stack items)
  141.             {
  142.                 items.Push(b); //помещаем вершину b в стек
  143.                 if (a == p[b]) //если предыдущей для вершины b является вершина а, то
  144.                 {
  145.                     items.Push(a); //помещаем а в стек и завершаем восстановление пути
  146.                 }
  147.                 else //иначе метод рекурсивно вызывает сам себя для поиска пути
  148.                 { //от вершины а до вершины, предшествующей вершине b
  149.                     WayDijkstr(a, p[b], p, ref items);
  150.                 }
  151.             }
  152.  
  153.             // /*/*//*/*//*/*//*/*//*/*//*/*/ ||||| \*\*\\*\*\\*\*\\*\*\\*\*\\*\*\
  154.             public void Add(int v1, int v2) //удалить ребро
  155.             {
  156.                 if (array[v1, v2] == 1 || array[v2, v1] == 1)
  157.                 {
  158.                     Console.WriteLine("Вершины смежны!");
  159.                 }
  160.                 else
  161.                 {
  162.                     array[v1, v2] = 1;
  163.                     array[v2, v1] = 1;
  164.                     Console.WriteLine("Выполнено");
  165.                 }
  166.             }
  167.         }//конец вложенного класса
  168.  
  169.         private Node graph; //закрытое поле, реализующее АТД «граф»
  170.  
  171.         public Graph(string name) //конструктор внешнего класса
  172.         {
  173.             using (StreamReader fileIn = new StreamReader("../../input.txt"))
  174.             {
  175.                 int n = int.Parse(fileIn.ReadLine());
  176.                 int[,] a = new int[n, n];
  177.                 for (int i = 0; i < n; i++)
  178.                 {
  179.                     string line = fileIn.ReadLine();
  180.                     string[] mas = line.Split(' ');
  181.                     for (int j = 0; j < n; j++)
  182.                     {
  183.                         a[i, j] = int.Parse(mas[j]);
  184.                     }
  185.                 }
  186.                 graph = new Node(a);
  187.             }
  188.         }
  189.  
  190.         //выводит матрицу смежности
  191.         public void Show()
  192.         {
  193.             for (int i = 0; i < graph.Size; i++)
  194.             {
  195.                 for (int j = 0; j < graph.Size; j++)
  196.                 {
  197.                     Console.Write("{0,4}", graph[i, j]);
  198.                 }
  199.                 Console.WriteLine();
  200.             }
  201.         }
  202.  
  203.         public void Dfs(int v)
  204.         {
  205.             graph.NovSet();//помечаем все вершины графа как непросмотренные
  206.             graph.Dfs(v); //запускаем алгоритм обхода графа в глубину
  207.             Console.WriteLine();
  208.         }
  209.  
  210.         public void Reachable(int u) //на основе вспомогательного массива nov выводит на экран истоки
  211.         {
  212.             bool[] used = new bool[graph.Size];
  213.             for (int i = 0; i < graph.Size; i++)
  214.             {
  215.                 if (i != u)
  216.                 {
  217.                     used = graph.Reach(i);
  218.                     if (used[u] == false)
  219.                     {
  220.                         Console.Write("{0} ", i);
  221.                     }
  222.                 }
  223.             }
  224.  
  225.         }
  226.  
  227.         // /*/*//*/*//*/*//*/*//*/*//*/*/ ||||| \*\*\\*\*\\*\*\\*\*\\*\*\\*\*\
  228.         public void minDistance(int v)
  229.         {
  230.             graph.NovSet(); //помечаем все вершины графа как непросмотренные
  231.             int[] p;
  232.             long[] d = graph.Dijkstr(v, out p); //запускаем алгоритм Дейкстры
  233.  
  234.             long min = 99;
  235.  
  236.             for (int i = 0; i < p.Length; i++)
  237.             {
  238.                 if (d[i] < min && d[i] != int.MinValue && d[i] != 0)
  239.                 {
  240.                     min = d[i];
  241.                 }
  242.             }
  243.  
  244.             if (min == 99)
  245.             {
  246.                 Console.WriteLine("Из заданной вершины другие вершины недостижимы");
  247.             }
  248.             else
  249.             {
  250.                 Console.Write("Ближе всего к вершине {0}: ", v);
  251.                 for (int i = 0; i < d.Length; i++)
  252.                 {
  253.                     if (d[i] == min)
  254.                     {
  255.                         Console.Write("{0} ", i);
  256.                     }
  257.                 }
  258.             }
  259.         }
  260.  
  261.         public void Fount(int v)
  262.         {
  263.             int temp = 0;
  264.             graph.NovSet();//помечаем все вершины графа как непросмотренные
  265.             int[] p;
  266.             long[] d = graph.Dijkstr(v, out p); //запускаем алгоритм Дейкстры
  267.             Console.Write("Вершинa {0} ", v);
  268.             for (int i = 0; i < graph.Size; i++)
  269.             {
  270.                 if (i != v)
  271.                 {
  272.                     if (d[i] != int.MaxValue)
  273.                     {
  274.                         temp++;
  275.                         Stack items = new Stack();
  276.                         graph.WayDijkstr(v, i, p, ref items);
  277.                     }
  278.                 }
  279.             }
  280.  
  281.             FindFount(temp);
  282.         }
  283.  
  284.         public void FindFount(int temp)
  285.         {
  286.             if (graph.Size - 1 == temp)
  287.             {
  288.                 Console.WriteLine("является истоком");
  289.             }
  290.             else Console.WriteLine("не является истоком");
  291.         }
  292.  
  293.         public void Add(int v1, int v2) //добавить ребро
  294.         {
  295.             graph.Add(v1, v2);
  296.         }
  297.         // \*\*\\*\*\\*\*\\*\*\\*\*\\*\*\ ||||| /*/*//*/*//*/*//*/*//*/*//*/*/
  298.     }//конец класса Graph
  299.  
  300.     class Program
  301.     {
  302.         static void Main(string[] args)
  303.         {
  304.             Graph g = new Graph("input.txt");
  305.             Console.WriteLine("Graph:");
  306.             g.Show();
  307.             Console.WriteLine();
  308.             /*
  309.             //task_4
  310.             Console.WriteLine("Задайте не смежные вершины");
  311.             Console.WriteLine("Вершина a: ");
  312.             int numA = int.Parse(Console.ReadLine());
  313.             Console.WriteLine("Вершина b: ");
  314.             int numB = int.Parse(Console.ReadLine());
  315.             g.Add(numA, numB);
  316.             g.Show();
  317.             Console.WriteLine();
  318.             */
  319.             /*
  320.             //task 4
  321.             for (int i = 0; i < 5; i++)
  322.             {
  323.                 g.Fount(i);
  324.             }
  325.             */
  326.             /*
  327.             //task 16
  328.             Console.WriteLine("Задайте вершину: ");
  329.             int v = int.Parse(Console.ReadLine());
  330.             g.minDistance(v);
  331.             */
  332.             Console.ReadKey();
  333.         }
  334.  
  335.     }
  336. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement