Advertisement
Ser1ousSAM

Graph analizer

Dec 2nd, 2022
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.78 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <string_view>
  5. #include <sstream>
  6. #include <map>
  7. #include <set>
  8.  
  9. using namespace std;
  10.  
  11. bool is_number(const std::string &s) {
  12. std::string::const_iterator it = s.begin();
  13. while (it != s.end() && std::isdigit(*it)) ++it;
  14. return !s.empty() && it == s.end();
  15. }
  16.  
  17. void get_number_convert(int &first, int &second) {
  18. string input;
  19. while (true) {
  20. getline(cin, input);
  21. string word;
  22. stringstream iss(input);
  23. bool isMinus = 0;
  24. bool zero = 0;
  25. while (iss >> word) {
  26. if (word[0] == '-' && word[1] == '1') {
  27. isMinus = 1;
  28. word[0] = '0';
  29. }
  30. if (is_number(word)) {
  31. if (zero == 0) {
  32. zero = 1;
  33. if (isMinus) {
  34. first = -1 * stoi(word);
  35. } else {
  36. first = stoi(word);
  37. }
  38. if (first == -1)
  39. return;
  40. } else {
  41. second = stoi(word);
  42. return;
  43. }
  44. }
  45. }
  46. cout << "please, do a correct int input" << '\n';
  47. }
  48. }
  49.  
  50. void get_correct_direction(bool &get_correct_direction) {
  51. string input;
  52. while (true) {
  53. getline(cin, input);
  54. if (is_number(input)) {
  55. int n = stoi(input);
  56. if (n == 0 || n == 1) {
  57. get_correct_direction = (n % 2 == 0);
  58. return;
  59. } else
  60. cout << "please, do a correct boolean input" << '\n';
  61. } else {
  62. cout << "please, do a correct boolean input" << '\n';
  63. }
  64. }
  65.  
  66. }
  67.  
  68. bool isContainValue(map<int, vector<int>> graph, const int &finding_key) {
  69. bool is_Contain = 0;
  70. for (const auto &[key, value]: graph) {
  71. if (finding_key == key) {
  72. is_Contain = true;
  73. break;
  74. }
  75. }
  76. if (is_Contain)
  77. return true;
  78. return false;
  79. }
  80.  
  81. void DFS_strong_connected(const int v, map<int, vector<int>> &graph, map<int, bool> &mark) {
  82. mark[v] = 1;
  83. for (const auto &[key, value]: graph) // Foreach edge
  84. {
  85. for (auto i: value) {
  86. if (mark[i] != 1) {
  87. DFS_strong_connected(i, graph, mark); // Load from the another node
  88. }
  89. }
  90. }
  91. }
  92.  
  93. void DFS_for_one_way(bool& is_reach_pin, const int &pin_vertex, const int v, map<int, vector<int>> &graph, map<int, bool> &mark, int &color,
  94. map<int, int> &colors) {
  95. mark[v] = 1;
  96. colors[v] = color;
  97. if (v == pin_vertex){
  98. is_reach_pin = true;
  99. return;
  100. }
  101. for (const auto &[key, value]: graph) // Foreach edge
  102. {
  103. for (auto i: value) {
  104. if (mark[i] != 1 && isContainValue(graph, key)) {
  105. DFS_for_one_way(is_reach_pin, pin_vertex, i, graph, mark, color, colors); // Load from the another node
  106. }
  107. }
  108. }
  109. }
  110.  
  111. void DFS(const int v, map<int, vector<int>> &graph, map<int, bool> &mark, int &color, map<int, int> &colors) {
  112. mark[v] = 1;
  113. colors[v] = color;
  114. for (const auto &[key, value]: graph) // Foreach edge
  115. {
  116. for (auto i: value) {
  117. if (mark[i] != 1) {
  118. DFS(i, graph, mark, color, colors); // Load from the another node
  119. }
  120. }
  121. }
  122. }
  123.  
  124. //only for the directed graphs
  125. int amountOfConnectivity(map<int, vector<int>> &graph) {
  126. int color = 1;
  127. int n = graph.size();
  128. map<int, int> colors;
  129. for (const auto &[key, value]: graph) {
  130. colors.insert(make_pair(key, 0));
  131. }
  132. map<int, bool> mark;
  133. for (const auto &[key, value]: graph) {
  134. mark.insert(make_pair(key, 0));
  135. }
  136. for (const auto &[key, value]: graph) {
  137. if (mark[key] != 1) {
  138. DFS(key, graph, mark, color, colors);
  139. color++;
  140. }
  141. }
  142. set<int> count;
  143. for (const auto &[key, value]: colors) {
  144. count.insert(value);
  145. }
  146. return count.size();
  147. }
  148.  
  149. bool isStrongConnection(map<int, vector<int>> &graph) {
  150. for (const auto &[key_external, value_external]: graph) {
  151. map<int, bool> mark;
  152. for (const auto &[key, value]: graph) {
  153. mark.insert(make_pair(key, 0));
  154. }
  155. DFS_strong_connected(key_external, graph, mark);
  156. for (const auto &[key, value]: mark) {
  157. if (mark[key] == false)
  158. return false;
  159. }
  160. }
  161. return true;
  162. }
  163.  
  164. bool isOneWayConnection(map<int, vector<int>> &graph) {
  165. map<int, bool> marks_for_each;
  166. for (const auto &[key, value]: graph) {
  167. for (auto i: value) {
  168. if (!marks_for_each.contains(i)) {
  169. marks_for_each.insert(make_pair(i, false));
  170. }
  171. }
  172. }
  173. for (const auto &[key_external, value_external]: graph) {
  174. const int pin_vertex = key_external;
  175. bool is_reach_vertex = false;
  176. for(const auto &[key_in, value_in]: graph){
  177. int color = 1;
  178. map<int, int> colors;
  179. for (const auto &[key, value]: graph) {
  180. colors.insert(make_pair(key, 0));
  181. }
  182. map<int, bool> mark;
  183. for (const auto &[key, value]: graph) {
  184. mark.insert(make_pair(key, 0));
  185. }
  186. DFS_for_one_way(is_reach_vertex, pin_vertex, key_in, graph, mark, color, colors);
  187. }
  188. if (is_reach_vertex)
  189. marks_for_each[key_external] = true;
  190. }
  191. for (const auto &[key, value]: marks_for_each) {
  192. if (!marks_for_each[key])
  193. return false;
  194. }
  195. return true;
  196. }
  197.  
  198.  
  199. bool isWeak(map<int, vector<int>> &graph) {
  200. map<int, vector<int>> temp_graph;
  201.  
  202. for(const auto& [key, values] : graph){
  203. for(auto value : values){
  204. if(temp_graph.contains(key)){
  205. temp_graph[key].push_back(value);
  206. } else{
  207. temp_graph.insert(make_pair(key, value));
  208. }
  209. if (key != value){
  210. temp_graph[value].push_back(key);
  211. }
  212. }
  213. }
  214. if (amountOfConnectivity(temp_graph) == 1)
  215. return true;
  216. return false;
  217. };
  218.  
  219. void print_map(std::string_view comment, const map<int, vector<int>> &m) {
  220. std::cout << comment << '\n';
  221. for (const auto &[key, value]: m) {
  222. std::cout << '[' << key << "] = ";
  223. for (auto i: value)
  224. cout << i << "; ";
  225. cout << '\n';
  226. }
  227.  
  228. std::cout << '\n';
  229. }
  230.  
  231. int calculateCountOfVertices(map<int, vector<int>> &graph) {
  232. set<int> vertecies;
  233. for (const auto &[key, value]: graph) {
  234. vertecies.insert(key);
  235. for (auto i: value)
  236. vertecies.insert(i);
  237. }
  238. return vertecies.size();
  239. }
  240.  
  241. int calculateCountOfLoops(map<int, vector<int>> &graph) {
  242. int count = 0;
  243. for (const auto &[key, value]: graph) {
  244. for (auto i: value) {
  245. if (key == i) {
  246. count++;
  247. }
  248. }
  249. }
  250. return count;
  251. }
  252.  
  253. int calculateCountOfEdges(map<int, vector<int>> &graph) {
  254. int count = 0;
  255. for (const auto &[key, value]: graph) {
  256. for (auto i: value) {
  257. count++;
  258. }
  259. }
  260. return count;
  261. }
  262.  
  263. int calculateMaxDegreeOut(map<int, vector<int>> &graph) {
  264. int maxx = 0;
  265. for (const auto &[key, value]: graph) {
  266. int temp = 0;
  267. for (auto i: value) {
  268. temp++;
  269. }
  270. if (temp > maxx)
  271. maxx = temp;
  272. }
  273. return maxx;
  274. }
  275.  
  276. int calculateMaxDegreeIn(map<int, vector<int>> &graph) {
  277. map<int, int> maxx_vals;
  278. for (const auto &[key, value]: graph) {
  279. maxx_vals.insert(make_pair(key, 0));
  280. }
  281. for (const auto &[key, value]: graph) {
  282. for (auto i: value) {
  283. maxx_vals[i]++;
  284. }
  285. }
  286. int maxx = 0;
  287. for (const auto &[key, value]: maxx_vals) {
  288. if (value > maxx)
  289. maxx = value;
  290. }
  291. return maxx;
  292. }
  293.  
  294. int calculateMaxDegreeInAndOut(map<int, vector<int>> &graph) {
  295. int maxx = 0;
  296. for (const auto &[key, value]: graph) {
  297. int temp = 0;
  298. for (auto i: value) {
  299. temp++;
  300. if (i == key)
  301. temp++;
  302. }
  303. if (temp > maxx) {
  304. maxx = temp;
  305. }
  306. }
  307. return maxx;
  308. }
  309.  
  310. int main() {
  311. map<int, vector<int>> graph;
  312. cout << "Choose a type of graph(0 - Direct, 1 - Undirect):\n";
  313. bool isDirectedGraph = 0;
  314. get_correct_direction(isDirectedGraph);
  315. cout
  316. << "Enter edges with 2 positive integer nodes separated by a space, on one line you can put the only one edge. To finish an input put -1 in a first node.\n";
  317. int first, second;
  318. while (true) {
  319. get_number_convert(first, second);
  320. if (first == -1) {
  321. break;
  322. }
  323. if (graph.contains(first)) {
  324. graph[first].push_back(second);
  325. } else {
  326. graph.insert(make_pair(first, vector<int>() = {second}));
  327. }
  328. if (!isDirectedGraph && second != first) {
  329. graph[second].push_back(first);
  330. }
  331. }
  332. print_map("Your graph by a list of vertices:", graph);
  333. int countOfVertices = calculateCountOfVertices(graph);
  334. int countOfLoops = calculateCountOfLoops(graph);
  335. int countOfEdges = calculateCountOfEdges(graph);
  336. countOfEdges -= countOfLoops;
  337. if (!isDirectedGraph) {
  338. countOfEdges /= 2;
  339. }
  340.  
  341. cout << "Count Of Vertices:" << countOfVertices << '\n';
  342. cout << "Count Of Loops:" << countOfLoops << '\n';
  343. cout << "Count Of Edges:" << countOfEdges << '\n';
  344. if (isDirectedGraph) {
  345. cout << "Max degree of your directed graph is:" << '\n';
  346. cout << "In vertex:" << calculateMaxDegreeIn(graph) << '\n';
  347. cout << "Out of vertex:" << calculateMaxDegreeOut(graph) << '\n';
  348. } else {
  349. cout << "Max degree of your Undirected graph is:" << calculateMaxDegreeInAndOut(graph) << '\n';
  350. }
  351. if (!isDirectedGraph) {
  352. int countConnections = amountOfConnectivity(graph);
  353. if (countConnections == 1) {
  354. cout << "Connected graph";
  355. } else {
  356. cout << "Unconnected graph";
  357. }
  358. cout << '\n';
  359. cout << "Connections count:" << countConnections << '\n';
  360. } else {
  361. if (isStrongConnection(graph)) {
  362. cout << "Strong connected graph\n";
  363. }
  364. else if (isOneWayConnection(graph)) {
  365. cout << "One-way connected graph\n";
  366. } else if (isWeak(graph)) {
  367. cout << "Weak connected graph";
  368. } else {
  369. cout << "Unconnected graph\n";
  370. }
  371. }
  372. return 0;
  373. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement