Advertisement
Infiniti_Inter

22- III

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