답안 #244525

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
244525 2020-07-04T09:11:55 Z oolimry Pipes (CEOI15_pipes) C++14
90 / 100
1303 ms 12564 KB
//HAPPY BIRTHDAY!!!
#include <bits/stdc++.h>
#define push_back emplace_back
using namespace std;
typedef pair<int,int> ii;

struct UFDS{
	int n;
	int p[100005];
	
	void init(int _n){
		n = _n;
		for(int i = 1;i <= n;i++) p[i] = i;
	}
	
	int find(int u){
		if(p[u] == u) return u;
		else{
			p[u] = find(p[u]);
			return p[u];
		}
	}
	
	void unionSet(int u, int P){
		u = find(u); P = find(P);
		if(u == P) return;
		p[u] = P;
	}
} tree, bridge;

vector<int> nodes[100005];
int p[100005];
int depth[100005];
vector<ii> possible;

void reroot(int u){
	vector<int> order;
	while(u != 0){
		order.push_back(u);
		u = p[u];
	}
	
	int sz = order.size(); order.push_back(0);
	for(int i = 0;i < sz;i++){
		p[order[i+1]] = order[i];
	}
	order.clear();
}

vector<int> adj[100005];
void dfs(int u){
	for(int v : adj[u]){
		depth[v] = depth[u] + 1;
		dfs(v);
	}
}

void redepth(int u){
	vector<int> V = nodes[u];
	
	for(int u : V){
		if(p[u] != 0) adj[p[u]].push_back(u);
	}
	
	depth[u] = 0;
	dfs(u);
	
	for(int u : V){
		adj[u].clear();
	}
}



signed main(){
	ios_base::sync_with_stdio(false); cin.tie(0);
	
	int n, E; cin >> n >> E;
	
	tree.init(n+2); bridge.init(n+2);
	
	for(int i = 1;i <= n;i++) nodes[i].emplace_back(i);
	
	while(E--){
		int u, v; cin >> u >> v;
		if(bridge.find(u) == bridge.find(v)) continue;
		
		if(tree.find(u) == tree.find(v)){ ///bridge formed
			
			vector<int> path;
			
			while(u != v){
				if(depth[u] > depth[v]) swap(u,v); ///v is deeper now
				
				path.push_back(v);
				v = p[v];
			}
			
			int P = u;
			//cout << P << "\n";
			for(int x : path){
				p[x] = P;
				p[x] = P;
				depth[x] = depth[P]+1;
				bridge.unionSet(x, P);
			}
		}
		else{ ///connect two trees to 1 tree
			int U = tree.find(u), V = tree.find(v);
			
			if(nodes[U].size() > nodes[V].size()){
				swap(U,V);
				swap(u,v);
			}
			
			//tree.unionSet(U, V);
			tree.p[U] = V;
			reroot(u);
			redepth(u);
			
			p[u] = v;
			while(!nodes[U].empty()){
				int B = nodes[U].back();
				depth[B] += depth[v] + 1;
				nodes[V].emplace_back(B);
				nodes[U].pop_back();
			}
			
			//cout << u << " " << v << ":\n";
			//for(int i = 1;i <= n;i++) cout << p[i] << " ";
			//cout << "\n";
			//for(int i = 1;i <= n;i++) cout << depth[i] << " ";
			//cout << "\n";
			possible.push_back(ii(u,v));
		}
	}
	
	for(ii e : possible){
		
		if(bridge.find(e.first) != bridge.find(e.second)){
			cout << e.first << " " << e.second << "\n";;
		}
		
		
	}
}
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 4992 KB Output is correct
2 Correct 8 ms 5120 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 13 ms 5376 KB Output is correct
2 Incorrect 14 ms 5376 KB Wrong number of edges
# 결과 실행 시간 메모리 Grader output
1 Correct 115 ms 5376 KB Output is correct
2 Correct 112 ms 5360 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 181 ms 5760 KB Output is correct
2 Correct 207 ms 5964 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 305 ms 6656 KB Output is correct
2 Correct 271 ms 7132 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 467 ms 10132 KB Output is correct
2 Correct 428 ms 10704 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 658 ms 10644 KB Output is correct
2 Correct 674 ms 11076 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 870 ms 11756 KB Output is correct
2 Correct 837 ms 12428 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1065 ms 11752 KB Output is correct
2 Correct 1041 ms 12564 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1303 ms 11544 KB Output is correct
2 Correct 1250 ms 12464 KB Output is correct