Advertisement
dipBRUR

Bridge Tree

Oct 4th, 2018
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.89 KB | None | 0 0
  1. static const int maxn = 1e5 + 5;
  2.  
  3. struct node
  4. {
  5. int v, e;
  6. node(int vv = 0, int ee = 0) : v(vv), e(ee) {}
  7. };
  8.  
  9. vector <node> graph[maxn];
  10. int dfsTime, dis[maxn], low[maxn];
  11. bool isBridge[maxn], vis[maxn];
  12. int totalBridge;
  13.  
  14. void findBridge(int u, int p = -1)
  15. {
  16. vis[u] = 1;
  17. dis[u] = low[u] = dfsTime++;
  18. for (auto &it : graph[u])
  19. {
  20. int v = it.v;
  21. int e = it.e;
  22. if (v == p)
  23. continue;
  24. if (!vis[v])
  25. {
  26. findBridge(v, u);
  27. low[u] = min(low[u], low[v]);
  28. if (dis[u] < low[v])
  29. {
  30. isBridge[e] = 1;
  31. totalBridge++;
  32. }
  33. }
  34. else
  35. {
  36. low[u] = min(low[u], dis[v]);
  37. }
  38. }
  39. }
  40.  
  41. int compo;
  42. bool used[maxn];
  43. vector <int> tree[maxn];
  44.  
  45.  
  46. void bridgeTree(int src)
  47. {
  48. used[src] = 1;
  49. int cur_compo = compo;
  50. queue <int> PQ;
  51. PQ.push(src);
  52. while(!PQ.empty())
  53. {
  54. int u = PQ.front(); PQ.pop();
  55. for (auto &it : graph[u])
  56. {
  57. int v = it.v;
  58. int e = it.e;
  59. if (used[v])
  60. continue;
  61. if (isBridge[e])
  62. {
  63. compo++;
  64. tree[cur_compo].push_back(compo);
  65. tree[compo].push_back(cur_compo);
  66. bridgeTree(v);
  67. }
  68. else
  69. {
  70. PQ.push(v);
  71. used[v] = 1;
  72. }
  73. }
  74. }
  75. }
  76. int maxDis, maxDisNode;
  77.  
  78. void dfs(int u, int p, int d)
  79. {
  80. if (d > maxDis)
  81. {
  82. maxDis = d;
  83. maxDisNode = u;
  84. }
  85. for (int v : tree[u])
  86. {
  87. if (v == u)
  88. continue;
  89. dfs(v, u, d+1);
  90. }
  91. }
  92.  
  93. void init()
  94. {
  95. dfsTime = 0;
  96. totalBridge = 0;
  97. compo = 1;
  98. for (int i = 0; i < maxn; i++)
  99. {
  100. vis[i] = 0;
  101. used[i] = 0;
  102. dis[i] = 0;
  103. low[i] = 0;
  104. isBridge[i] = 0;
  105. graph[i].clear();
  106. tree[i].clear();
  107. }
  108. }
  109.  
  110. int main()
  111. {
  112. int tc;
  113. cin >> tc;
  114. for (int tcase = 1; tcase <= tc; tcase++)
  115. {
  116. init();
  117. int n, m;
  118. cin >> n >> m;
  119. int src = n;
  120. for (int e = 1; e <= m; e++)
  121. {
  122. int u, v;
  123. cin >> u >> v;
  124. graph[u].push_back(v);
  125. graph[v].push_back(u);
  126. src = min(src, min(u, v));
  127. }
  128. findBridge(src);
  129. bridgeTree(src);
  130. maxDis = -1;
  131. maxDisNode = -1;
  132. dfs(1, -1, 0);
  133. maxDis = -1;
  134. dfs(maxDisNode, -1, 0);
  135. cout << (totalBridge � maxDis) << endl;
  136. }
  137. } static const int maxn = 1e5 + 5;
  138.  
  139. struct node
  140. {
  141. int v, e;
  142. node(int vv = 0, int ee = 0) : v(vv), e(ee) {}
  143. };
  144.  
  145. vector <node> graph[maxn];
  146. int dfsTime, dis[maxn], low[maxn];
  147. bool isBridge[maxn], vis[maxn];
  148. int totalBridge;
  149.  
  150. void findBridge(int u, int p = -1)
  151. {
  152. vis[u] = 1;
  153. dis[u] = low[u] = dfsTime++;
  154. for (auto &it : graph[u])
  155. {
  156. int v = it.v;
  157. int e = it.e;
  158. if (v == p)
  159. continue;
  160. if (!vis[v])
  161. {
  162. findBridge(v, u);
  163. low[u] = min(low[u], low[v]);
  164. if (dis[u] < low[v])
  165. {
  166. isBridge[e] = 1;
  167. totalBridge++;
  168. }
  169. }
  170. else
  171. {
  172. low[u] = min(low[u], dis[v]);
  173. }
  174. }
  175. }
  176.  
  177. int compo;
  178. bool used[maxn];
  179. vector <int> tree[maxn];
  180.  
  181.  
  182. void bridgeTree(int src)
  183. {
  184. used[src] = 1;
  185. int cur_compo = compo;
  186. queue <int> PQ;
  187. PQ.push(src);
  188. while(!PQ.empty())
  189. {
  190. int u = PQ.front(); PQ.pop();
  191. for (auto &it : graph[u])
  192. {
  193. int v = it.v;
  194. int e = it.e;
  195. if (used[v])
  196. continue;
  197. if (isBridge[e])
  198. {
  199. compo++;
  200. tree[cur_compo].push_back(compo);
  201. tree[compo].push_back(cur_compo);
  202. bridgeTree(v);
  203. }
  204. else
  205. {
  206. PQ.push(v);
  207. used[v] = 1;
  208. }
  209. }
  210. }
  211. }
  212. int maxDis, maxDisNode;
  213.  
  214. void dfs(int u, int p, int d)
  215. {
  216. if (d > maxDis)
  217. {
  218. maxDis = d;
  219. maxDisNode = u;
  220. }
  221. for (int v : tree[u])
  222. {
  223. if (v == u)
  224. continue;
  225. dfs(v, u, d+1);
  226. }
  227. }
  228.  
  229. void init()
  230. {
  231. dfsTime = 0;
  232. totalBridge = 0;
  233. compo = 1;
  234. for (int i = 0; i < maxn; i++)
  235. {
  236. vis[i] = 0;
  237. used[i] = 0;
  238. dis[i] = 0;
  239. low[i] = 0;
  240. isBridge[i] = 0;
  241. graph[i].clear();
  242. tree[i].clear();
  243. }
  244. }
  245.  
  246. int main()
  247. {
  248. int tc;
  249. cin >> tc;
  250. for (int tcase = 1; tcase <= tc; tcase++)
  251. {
  252. init();
  253. int n, m;
  254. cin >> n >> m;
  255. int src = n;
  256. for (int e = 1; e <= m; e++)
  257. {
  258. int u, v;
  259. cin >> u >> v;
  260. graph[u].push_back(v);
  261. graph[v].push_back(u);
  262. src = min(src, min(u, v));
  263. }
  264. findBridge(src);
  265. bridgeTree(src);
  266. maxDis = -1;
  267. maxDisNode = -1;
  268. dfs(1, -1, 0);
  269. maxDis = -1;
  270. dfs(maxDisNode, -1, 0);
  271. cout << (totalBridge � maxDis) << endl;
  272. }
  273. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement