답안 #366004

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
366004 2021-02-12T17:39:51 Z kostia244 Pipes (CEOI15_pipes) C++17
100 / 100
2957 ms 13688 KB
#include<bits/stdc++.h>//memory usage is jumpting too much
#define all(x) begin(x), end(x)
using namespace std;
using ll = long long;
const int maxn = 1e5+1, lg = 11;
struct dsu {
	int p[maxn];
	dsu(int n = 0) {
		for(int i = 0; i <= n; i++) p[i] = -1;
	}
	int par(int i) { return p[i] < 0 ? i : p[i] = par(p[i]); }
	void join(int u, int v) {
		u = par(u), v = par(v);
		if(u == v) return;
		p[u] += p[v];
		p[v] = u;
	}
	bool connected(int u, int v) {
		return par(u) == par(v);
	}
};
dsu comp;
int n, m;
int h[maxn], eval[maxn], lval[maxn], p[maxn][lg];
array<int, 2> elist[maxn];
vector<array<int, 2>> g[maxn];
void accumulate(int v, int p, int eid) {
	for(auto [i, id] : g[v]) if(i != p) {
		accumulate(i, v, id);
		lval[v] += lval[i];
	}
	if(eid != -1 && lval[v]) {
		eval[eid] += lval[v];
		//cout << elist[eid][0] << " " << elist[eid][1] << " += " << lval[v] << endl;
	}
}
void attach(int v, int pr) {
	lval[v] = 0;
	p[v][0] = pr;
	for(int i = 1; i < lg; i++) {
		p[v][i] = p[v][i-1];
		p[v][i] = p[p[v][i]][i-1];
		p[v][i] = p[p[v][i]][i-1];
	}
	for(auto [i, id] : g[v]) if(i != pr) {
		h[i] = h[v]+1;
		attach(i, v);
	}
}
int ESZ = 0;
int lca(int u, int v) {
	if(h[u] > h[v]) swap(u, v);
	int dif = h[v]-h[u];
	for(int i = 0; i < lg; i++) {
		if(dif%3) v = p[v][i], dif--;
		if(dif%3) v = p[v][i];
		dif /= 3;
	}
	if(u == v) return u;
	for(int i = lg; i--;) {
		if(p[v][i] != p[u][i]) v = p[v][i], u = p[u][i];
		if(p[v][i] != p[u][i]) v = p[v][i], u = p[u][i];
	}
	return p[u][0];
}
void add_edge(int u, int v) {
	if(comp.connected(u, v)) {
		int L = lca(u, v);
		//cout << u << " " << v << " lca = " << L << endl;
		lval[u]++, lval[v]++, lval[L] -= 2;
	} else {
		int ru = comp.par(u), rv = comp.par(v);
		if(-comp.p[ru] < -comp.p[rv]) swap(u, v), swap(ru, rv);
		//cout << u<< " is god " << endl;
		comp.join(ru, rv);
		h[v] = h[u]+1;
		accumulate(rv, -1, -1);
		attach(v, u);
		g[u].push_back({v, ESZ});
		g[v].push_back({u, ESZ});
		elist[ESZ++] = {u, v};
	}
}
void debug(int v, int p = -1) {
	for(auto [i, id] : g[v]) if(i != p) {
		cout << v << " -> " << i << endl;
		debug(i, v);
	}
}
int main() {
	cin.tie(0)->sync_with_stdio(0);
	cin >> n >> m;
	comp = dsu(n+1);
	for(int f, t; m--;) {
		cin >> f >> t;
		add_edge(f, t);
		//cout << m << endl;
		//for(int i = 1; i <= n; i++) if(comp.par(i) == i) {
		//	debug(i);
		//}
	}
	accumulate(comp.par(1), -1, -1);
	for(int i = 0; i < ESZ; i++) if(!eval[i]) cout << elist[i][0] << " " << elist[i][1] << '\n';
}
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 3180 KB Output is correct
2 Correct 2 ms 3052 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 3564 KB Output is correct
2 Correct 8 ms 3564 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 176 ms 3692 KB Output is correct
2 Correct 162 ms 3564 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 316 ms 4076 KB Output is correct
2 Correct 364 ms 4076 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 562 ms 5612 KB Output is correct
2 Correct 480 ms 6124 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 900 ms 10348 KB Output is correct
2 Correct 767 ms 10348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1362 ms 11352 KB Output is correct
2 Correct 1169 ms 11136 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2061 ms 13224 KB Output is correct
2 Correct 2135 ms 13420 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2475 ms 13308 KB Output is correct
2 Correct 2489 ms 13688 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2957 ms 12860 KB Output is correct
2 Correct 2500 ms 13556 KB Output is correct