zoj 3261 - Connections in Galaxy War(并查集)
2013-10-25 17:52
429 查看
题意:(from:http://blog.csdn.net/ggggiqnypgjg/article/details/6621481)
有n个星球,每个星球有一定的power值,某些星球是直接或间接相连的。。。当某个星球想求助时会找到相连的里面的power值最大而且大于自己的一个星球。。。先在给定这些power值并给定两两相连的信息,然后又q个操作,destroy a b是删除a b直接相连的边(保证存在),query
a求向谁求助,如果不能求助输出-1 。。。
思路:
虽然并查集是不可逆的,但是我们可以离线处理,把删边变为填边,即把那些需要删掉的边一开始就不加进去,而是倒着处理那些操作,当碰到删边的时候我们再把要删的边加进去,这样并查集就很简单了,最后再把答案倒着输出就可以了。
代码如下:
有n个星球,每个星球有一定的power值,某些星球是直接或间接相连的。。。当某个星球想求助时会找到相连的里面的power值最大而且大于自己的一个星球。。。先在给定这些power值并给定两两相连的信息,然后又q个操作,destroy a b是删除a b直接相连的边(保证存在),query
a求向谁求助,如果不能求助输出-1 。。。
思路:
虽然并查集是不可逆的,但是我们可以离线处理,把删边变为填边,即把那些需要删掉的边一开始就不加进去,而是倒着处理那些操作,当碰到删边的时候我们再把要删的边加进去,这样并查集就很简单了,最后再把答案倒着输出就可以了。
代码如下:
const int N = 10005; const int M = 20005; const int Q = 50005; map<pair<int, int>, int>fmap; typedef pair<int,int>Pair; typedef pair<pair<int,int>,int>Element; struct Rec { int a, b; }rec[M], que[Q]; int p , power , flag[M]; int find(int x) { return p[x]==x?x:p[x]=find(p[x]); } void unionset(int a, int b) { int x = find(a); int y = find(b); if(x!=y&&power[x]<power[y]) p[x] = y; if(x!=y&&power[x]>power[y]) p[y] = x; if(x!=y&&power[x]==power[y]&&x>y) p[x] = y; if(x!=y&&power[x]==power[y]&&x<y) p[y] = x; } int main() { int n, m, a, b, q, k = 0; char tmp[20]; while(~scanf("%d", &n)) { fmap.clear(); for(int i = 0; i < n; ++i) scanf("%d", &power[i]), p[i] = i; scanf("%d", &m); for(int i = 0; i < m; ++i) { scanf("%d%d", &a, &b); if(a>b) swap(a,b); Pair first(a,b); Element element(first, i); fmap.insert(element); rec[i] = {a,b}; } scanf("%d", &q); memset(flag,0,sizeof(flag)); for(int i = 0; i < q; ++i) { scanf("\n%s", tmp); if(tmp[0]=='q') { scanf("%d", &a); que[i] = {-1,a}; } else { scanf("%d%d", &a, &b); if(a>b) swap(a,b); Pair first(a,b); int t = fmap[first]; flag[t] = 1; que[i] = {a,b}; } } for(int i = 0; i < m; ++i) if(!flag[i]) unionset(rec[i].a, rec[i].b); int cnt = 0, ans[q], f; for(int i = q-1; i >= 0; --i) { if(que[i].a!=-1) unionset(que[i].a, que[i].b); else { f = find(que[i].b); ans[cnt++] = power[f]==power[que[i].b]?-1:f; } } if(k++) printf("\n"); for(int i = cnt-1; i >= 0; --i) printf("%d\n", ans[i]); } return 0; }
相关文章推荐
- ZOJ-3261 Connections in Galaxy War 并查集 离线操作
- ZOJ 3261 Connections in GalaxyWar(并查集:离线处理)
- ZOJ 3261 Connections in Galaxy War(逆向并查集)
- ZOJ 3261 Connections in Galaxy War 并查集
- ZOJ 3261 Connections in Galaxy War (并查集)
- ZOJ 3261 Connections in Galaxy War 并查集
- ZOJ 3261 Connections in Galaxy War 反向用并查集
- ZOJ Problem Set - 3261 Connections in Galaxy War(并查集)
- ZOJ-3261-Connections in Galaxy War [逆向并查集]
- ZOJ 3261 Connections in Galaxy War(并查集)
- ZOJ 3261 Connections in Galaxy War (离线处理+逆向并查集)
- zoj 3261 Connections in Galaxy War 删边并查集模板
- ZOJ 3261 - Connections in Galaxy War ,并查集删边
- ZOJ ~ 3261 ~ Connections in Galaxy War (逆序并查集 + map)
- ZOJ-3261(Connections in Galaxy War)——并查集
- ZOJ 3261 Connections in Galaxy War (并查集)
- ZOJ 3261 Connections in Galaxy War【并查集】
- Zoj 3261 Connections in Galaxy War (逆向并查集)
- Zoj 3261 Connections in Galaxy War【逆序并查集】
- ZOJ 3261 Connections in Galaxy War【并查集】