Submission #106579

#TimeUsernameProblemLanguageResultExecution timeMemory
106579teomrnPipes (CEOI15_pipes)C++14
50 / 100
5085 ms7316 KiB
#include <stdio.h> #include <algorithm> #include <vector> #include <numeric> #include <assert.h> using namespace std; const int NMAX = 100010; struct UF { char r[NMAX]; int tata[NMAX]; UF() { iota(tata, tata + NMAX, 0); } int find(int x) { if (tata[tata[x]] != tata[x]) tata[x] = find(tata[x]); return tata[x]; } bool unite(int a, int b) { a = find(a); b = find(b); if (a == b) return 0; if (r[a] < r[b]) swap(a, b); if (r[a] == r[b]) { r[a]++; tata[b] = a; } else tata[b] = a; return 1; } } simple, strong; namespace Tree { int h[NMAX]; int father[NMAX]; int up[NMAX]; /// ultimul cu care stiu sigur ca m-am unit vector <int> adia[NMAX]; /// suma ar trebui sa fie max NMAX :) vector <pair <int, int>> single; int n; int _find(int nod) { if (up[up[nod]] != up[nod]) up[nod] = _find(up[nod]); return up[nod]; } int find(int nod) { up[nod] = _find(nod); while (strong.find(up[nod]) == strong.find(father[up[nod]])) { up[up[nod]] = father[up[nod]]; up[nod] = _find(nod); } return up[nod]; } void make_strong(int a, int b) { while (1) { a = find(a); b = find(b); if (a == b) return; if (h[a] < h[b]) swap(a, b); /// acum il unesc pe a cu tatal sau assert(strong.find(a) != strong.find(father[a])); assert(father[a] != 0); strong.unite(a, father[a]); up[a] = father[a]; } } void dfs(int nod, int tata) { father[nod] = tata; h[nod] = 1 + h[tata]; up[nod] = nod; for (auto i : adia[nod]) if (i != tata) dfs(i, nod); } void add_edge(int a, int b) { if (simple.unite(a, b)) { if (simple.r[a] < simple.r[b]) swap(a, b); adia[a].push_back(b); adia[b].push_back(a); dfs(b, a); } else make_strong(a, b); } void dfs_ans(int nod, int tata) { for (auto i : adia[nod]) { if (i == tata) continue; if (strong.find(i) != strong.find(nod)) single.push_back({ nod, i }); dfs_ans(i, nod); } } void get_ans() { for (int i = 1; i <= n; i++) if (father[i] == 0) dfs_ans(i, 0); } } int main() { int n, m, a, b; scanf("%d%d", &n, &m); Tree::n = n; iota(Tree::up, Tree::up + NMAX, 0); while (m--) { scanf("%d%d", &a, &b); Tree::add_edge(a, b); } Tree::get_ans(); for (auto i : Tree::single) printf("%d %d\n", i.first, i.second); return 0; }

Compilation message (stderr)

pipes.cpp: In function 'int main()':
pipes.cpp:123:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d%d", &n, &m);
     ~~~~~^~~~~~~~~~~~~~~~
pipes.cpp:128:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d%d", &a, &b);
         ~~~~~^~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...