码迷,mamicode.com
首页 > 其他好文 > 详细

zoj 3261 Connections in Galaxy War(并查集+离线逆向操作)

时间:2015-06-26 15:03:04      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:并查集   离线   



题目:给出一些点,每个点有权值,然后有一些边,相连。无向的。然后有一些操作

query a.表示从a出发的能到达的所有点权值最大的点的编号(相同取编号最小,而且权值要比自己大)

destory a,b 表示删除连接a,b的边

思路并查集,但是要逆向处理,所以先离线读入,从后向前处理,于是对于destroy操作,等价于连接两个点的操作,然后对于每个询问输出即可

#include<cstdio>  
#include<cstring>  
#include<cmath>  
#include<cstdlib>  
#include<iostream>  
#include<algorithm>  
#include<vector>  
#include<map>  
#include<queue>  
#include<stack> 
#include<string>
#include<map> 
#include<set>
#define eps 1e-6 
#define LL long long  
using namespace std;  

const int maxn = 10000 + 100;
const int INF = 0x3f3f3f3f;
int val[maxn]; 
int n, m, q;
set<pair<int, int> > edge;
stack<char> op;
stack<int> query;
stack<pair<int, int> > destroy;
stack<int> ans;
int fa[maxn];
int kase = 0;

int find(int x) {
	return x == fa[x] ? x : fa[x] = find(fa[x]);
}

void init() {
	edge.clear();
	for(int i = 0; i < n; i++) fa[i] = i;
	for(int i = 0; i < n; i++) cin >> val[i];
	cin >> m;
	while(m--) {
		int u, v; cin >> u >> v;
		edge.insert(make_pair(u, v));
	}
	cin >> q;
	while(q--) {
		char cmd[7]; cin >> cmd;
		int u, v;
		if(cmd[0] == 'q') {
			op.push('q');
			cin >> u;
			query.push(u);
		}
		else {
			op.push('d');
			cin >> u >> v;
			if(edge.count(make_pair(u, v))) edge.erase(make_pair(u, v));
			if(edge.count(make_pair(v, u))) edge.erase(make_pair(v, u));
			destroy.push(make_pair(u, v));
		}
	}
}

void solve() {
	if(kase++) cout << endl;
	for(set<pair<int, int> >::iterator it = edge.begin(); it != edge.end(); it++) {
		int u = (*it).first, v = (*it).second;
		if(val[find(u)] > val[find(v)]) {
			fa[fa[v]] = fa[u];
		}
		else if(val[fa[u]] == val[find(v)]) {
			if(fa[u] < fa[v]) fa[fa[v]] = fa[u];
			else fa[fa[u]] = fa[v];
		}
		else {
			fa[fa[u]] = fa[v];
		}
	}
	char cmd;
	while(!op.empty()) {
		cmd = op.top(); op.pop();
		if(cmd == 'q') {
			int qu = query.top(); query.pop();
			if(val[find(qu)] > val[qu]) ans.push(fa[qu]);
			else ans.push(-1);
		}
		else {
			pair<int, int> tmp = destroy.top(); destroy.pop();
			int u = tmp.first, v = tmp.second;
			if(val[find(u)] > val[find(v)]) {
				fa[fa[v]] = fa[u];
			}
			else if(val[fa[u]] == val[find(v)]) {
				if(fa[u] < fa[v]) fa[fa[v]] = fa[u];
				else fa[fa[u]] = fa[v];
			}
			else {
				fa[fa[u]] = fa[v];
			}
		}
	}
	while(!ans.empty()) {
		cout << ans.top() << endl;
		ans.pop();
	}
}

int main() {
	//freopen("input.txt", "r", stdin);
	while(scanf("%d", &n) == 1) {
		init();
		solve();
	}
}










zoj 3261 Connections in Galaxy War(并查集+离线逆向操作)

标签:并查集   离线   

原文地址:http://blog.csdn.net/u014664226/article/details/46649567

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!