Submission #38618

# Submission time Handle Problem Language Result Execution time Memory
38618 2018-01-05T06:02:19 Z farmersrice Pipes (CEOI15_pipes) C++14
100 / 100
1294 ms 14832 KB
#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#pragma GCC optimize ("O3")
//#pragma GCC target ("sse4")
#pragma GCC target ("avx,tune=native")
//Use above if bruteforcing with lots of small operations. Or just use it anytime, there's no downside. AVX is better slightly
/*
TASK: hidden
LANG: C++11
*/
using namespace std;
//using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int, int> pair2;
typedef pair<int, pair<int, int> > pair3;
typedef pair<int, pair<int, pair<int, int> > > pair4;
#define MAXN 100013
#define INF 1000000000000000000LL
#define mp make_pair
#define add push_back
#define remove pop

int n, m;
vector<int> adj[MAXN];
//vector<pair<int, int>> answer;

int depth[MAXN], lowestAdjDepth[MAXN];

struct UnionFind {
	int * id;
	int * size;
	int count;

	UnionFind(int sz) {
		id = new int[sz];
		size = new int[sz];
		count = sz;
		for (int i = 0; i < sz; i++) {
			size[i] = 1;
			id[i] = i;
		}
	}

	UnionFind(){}

	bool sameset(int p, int q) {
		return find(p) == find(q);
	}

	int find(int p) {
		if (p != id[p]) {
			id[p] = find(id[p]);
		}
		return id[p];
	}

	void merge(int p, int q) {
		int rootp = find(p);
		int rootq = find(q);
		if (rootp == rootq) return;

		if (size[rootp] < size[rootq]) {
			id[rootp] = rootq;
			size[rootq] += size[rootp];
		} else {
			id[rootq] = rootp;
			size[rootp] += size[rootq];
		}
		count--;
	}
} uf[2];

//returns subtree size
void solve(int current, int parent) {
	assert(depth[current] >= 1);

	lowestAdjDepth[current] = depth[current];

	//cout << "solving " << current << " lad dis " << lowestAdjDepth[current] << endl;
	bool t = false;
	for (int next : adj[current]) {
		if (next == parent && !t) {t = true; continue;}
 
		if (depth[next] >= 1) {
			lowestAdjDepth[current] = min(lowestAdjDepth[current], depth[next]);
		} else {
			//unvisited, let's go visit!
			depth[next] = depth[current] + 1;
 
			solve(next, current);
			lowestAdjDepth[current] = min(lowestAdjDepth[current], lowestAdjDepth[next]);

			//cout << "current is " << current << " lad next is " << lowestAdjDepth[next] << " depth current is " << depth[current] << endl;
			if (lowestAdjDepth[next] > depth[current]) {
				//the next node is in a biconnected component unaffected by current node
				//answer.add(mp(current, next));
				cout << current + 1 << ' ' << next + 1 << endl;
			}
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false); 
	cin.tie(NULL);

	cin >> n >> m;

	uf[0] = UnionFind(n);
	uf[1] = UnionFind(n);
	for (int i = 0; i < m; i++) {
		int a, b;
		cin >> a >> b;
		a--;b--;

		if (!uf[0].sameset(a, b)) {
			adj[a].add(b);
			adj[b].add(a);
			uf[0].merge(a, b);
		} else if (!uf[1].sameset(a, b)) {
			adj[a].add(b);
			adj[b].add(a);
			uf[1].merge(a, b);
		}
	}	

	for (int i = 0; i < n; i++) {
		if (depth[i] == 0) {
			depth[i] = 1;
			solve(i, -1);
		}
	}
	/*
	for (auto t : answer) {
		cout << t.first + 1 << ' ' << t.second + 1<< endl;
	}*/
}
# Verdict Execution time Memory Grader output
1 Correct 3 ms 2688 KB Output is correct
2 Correct 4 ms 2688 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 13 ms 3200 KB Output is correct
2 Correct 8 ms 3072 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 104 ms 3052 KB Output is correct
2 Correct 100 ms 2936 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 162 ms 3912 KB Output is correct
2 Correct 191 ms 3392 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 301 ms 5616 KB Output is correct
2 Correct 247 ms 5292 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 401 ms 11272 KB Output is correct
2 Correct 392 ms 7796 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 648 ms 12520 KB Output is correct
2 Correct 592 ms 9612 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 833 ms 14704 KB Output is correct
2 Correct 798 ms 9820 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1055 ms 14832 KB Output is correct
2 Correct 1066 ms 9860 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1294 ms 14292 KB Output is correct
2 Correct 1182 ms 11484 KB Output is correct