Advertisement
Proff_Ust

graph_shareParent

Nov 24th, 2019
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.80 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <fstream>
  4. #define MAX  10001
  5. using namespace std;
  6.  
  7. vector<int> g[MAX];//вектор для графа. номер строки соответствует вершине источнику,
  8.                    //в векторе перечислены всевершины назначения
  9. vector<int> gr[MAX];//транспонированный граф. нужен для обхода его в ширину, строится аналигично первому
  10. int used[MAX];//вспомогательный массив для поиска в ширину
  11.  
  12. int bfs(int v)//алгоритм поиска в ширину
  13. {
  14.     int Q[MAX];//очередь на основе массива. такая реализация выбрана потому
  15.                 //что нам надо сохранять вершины в очереди, после того, как мы их оттуда извлекли
  16.     int head = 0;//индекс головы
  17.     int tail = 1;//и хвоста очереди
  18.     Q[0] = v;//помещаем в очередь ту вершину, с которой начинаем обход
  19.     used[v] = 1;//и помечаем её посещенной
  20.     int from;
  21.     int to;
  22.     int count = 0;
  23.     while(head < tail)//пока очередь не пуста
  24.     {
  25.  
  26.         from = Q[head++];//вынимаем из очереди вершину
  27.         for(unsigned int i=0; i<gr[from].size(); i++)//и начинаем оход её смежных вершин
  28.         {
  29.             to = gr[from][i];//получаем смежную вершину
  30.             if(!used[to])//если она не посещена
  31.             {
  32.                 used[to] = 1;//помечаем посещенной
  33.                 Q[tail++] = to;//кладем в очередь
  34.                 count++;//и увеличиваем счетчик пар вершин в общим предком
  35.             }
  36.         }
  37.     }
  38. //после обхода транспонированного графа надо обойти те вершины, которые были посещены.
  39. //для этого перемещаем голову в начало очереди, не очищая её
  40.     head = 0;
  41.     while(head < tail)//обход аналогичен
  42.     {
  43.         from = Q[head++];
  44.         for(unsigned int i=0; i<g[from].size(); i++)
  45.         {
  46.             to = g[from][i];
  47.             if(!used[to])
  48.             {
  49.                 used[to] = 1;
  50.                 Q[tail++] = to;
  51.                 count++;
  52.             }
  53.         }
  54.     }
  55.     return count + 1;//возвращаем количество вершин в общим предком+1, чтобы учесть что вершина достижима сама из себя
  56. }
  57.  
  58. int main()
  59. {
  60.     setlocale(0, "");
  61.     ifstream f("input.txt");
  62.     if (!f)
  63.     {
  64.         cout << " We have a problem";
  65.         return -1;
  66.     }
  67.     int n, m;//кол-во вершин и ребер
  68.     int u, v;//считываемые вершины
  69.     int result = 0;
  70.     f>>n;//считываем из файла кол-во вершин
  71.     f>>m;//и ребер
  72.     for (int i=1;i<=m;i++)//цикл по ребрам
  73.     {
  74.         f>>u;//вершина источник
  75.         f>>v;//вершина назначение
  76.         g[u].push_back(v);//push_back - добавление значения в конец вектора
  77.         gr[v].push_back(u);//здесь происходит транспонирование нашего графа
  78.     }
  79.  
  80.     for(int i=1;i<= n;i++)//цикл по всем вершинам
  81.     {
  82.         for(int j=1;j<=n;j++)//обнуляем вспомогательный массив
  83.             used[j] = 0;
  84.         result = result + bfs(i);//и запускаем поиск
  85.     }
  86.     cout<<result;
  87. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement