Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace ConsoleApp1
- {
- class Program
- {
- static HashSet<int> dfs(int startNode, long[,] graph, bool killCycles=false)
- {
- /* Поиск в глубину, который умеет убивать циклы. */
- var visited = new HashSet<int>();
- var finished = new HashSet<int>();
- var stack = new Stack<int>();
- visited.Add(startNode);
- stack.Push(startNode);
- while (stack.Count != 0)
- {
- var node = stack.Pop();
- foreach (var nextNode in incidentNodes[node])
- {
- if (finished.Contains(nextNode)) continue;
- if (killCycles)
- {
- if (visited.Contains(nextNode)) {
- // 2 := "d" Убиваем циклы
- graph[node, nextNode] = 2;
- graph[nextNode, node] = 2;
- incidentNodes[node].Remove(nextNode);
- incidentNodes[nextNode].Remove(node);
- cost += d;
- break;
- }
- }
- visited.Add(nextNode);
- stack.Push(nextNode);
- }
- finished.Add(node);
- }
- return finished;
- }
- static long n;
- static long d;
- static long a;
- static long cost;
- static Dictionary<int, List<int>> incidentNodes;
- static void Main(string[] args)
- {
- // Ввод
- n = int.Parse(Console.ReadLine()); // Количество аэропортов (2 <= n <= 100)
- var s = Console.ReadLine().Split(); // Строка вида d a
- d = int.Parse(s[0]); // Стоимость удаления
- a = int.Parse(s[1]); // Стоимость добавления
- cost = 0; // Сколько нужно потратить в итоге
- var graph = new long[n, n];
- var colors = new Dictionary<int, int>(); // Каждому узлу ставим в соотвествие его "цвет"
- incidentNodes = new Dictionary<int, List<int>>();
- // Вводим граф
- for (var i = 0; i < n; i++)
- {
- var line = Console.ReadLine();
- var j = 0;
- incidentNodes[i] = new List<int>();
- foreach (var c in line)
- {
- graph[i, j] = int.Parse(c.ToString());
- if (c == '1') { incidentNodes[i].Add(j); }
- j++;
- }
- }
- // Убиваем циклы
- for(var i = 0; i<n;i++) dfs(i, graph, true);
- // Ищем компоненты связности
- var sNodes = 0;
- var result = dfs(0, graph);
- var currentColor = 0;
- foreach (var node in result)
- {
- colors[node] = currentColor;
- }
- sNodes += result.Count;
- while(sNodes < n)
- {
- for(var i = 0; i < n; i++)
- {
- if (!result.Contains(i))
- {
- result = dfs(i, graph, true);
- currentColor += 1;
- foreach (var node in result)
- {
- colors[node] = currentColor;
- }
- sNodes += result.Count;
- }
- }
- }
- /* Далее, проверяем каждое ребро (u, v).
- * Если между две вершины не инцидентны,
- * то проверим в какой компоненты связности они находятся.
- * Если в разных, то раскрашиваем эти вершины в один цвет и добавляем между ними ребро.*/
- for (var i = 0; i < n; i++)
- {
- for(var j = 0; j < n; j++)
- {
- if(graph[i, j] == 0)
- {
- if(colors[i] != colors[j])
- {
- graph[i, j] = 3;
- graph[j, i] = 3;
- cost += a;
- colors[j] = colors[i];
- result = dfs(j, graph);
- foreach (var node in result)
- {
- colors[node] = colors[j];
- }
- }
- }
- }
- }
- // Вывод
- Console.WriteLine(cost);
- for (var i = 0; i < n; i++) {
- for (var j = 0; j < n; j++) {
- if (graph[i, j] == 2) Console.Write("d");
- else if (graph[i, j] == 3) Console.Write("a");
- else Console.Write("0");
- }
- Console.Write("\n");
- }
- Console.ReadKey();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement