Advertisement
Tvor0zhok

СиАКОД графы 3

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