zoj 3261 Connections in Galaxy War 删边并查集模板

来源:互联网 发布:eai是什么软件 编辑:程序博客网 时间:2024/05/16 18:35

题意:n个点m条边,q个操作 1:查询x所在集合里面的权值最大的那个点,没有输出-1。2:删除连接a~b的边。

将所有的操作保存下来,然后倒着推,建完边之后删去所有的边,然后每次遇到删边操作的时候就重新添上要删的边,(即把连接边的两点加紧同一个集合里),查询的话就是普通的并查集

#include <map>#include <set>#include <queue>#include <stack>#include <vector>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1#define pi acos(-1.0)#define eps 1e-8typedef long long ll;const int inf = 0x3f3f3f3f;const int N = 10010;vector <int> ve[N];stack <int> s;int fa[N], r[N], p[N];struct node{int u, v;}a[N * 5];int n, m, q;void init(){while( !s.empty() )s.pop();for( int i = 1; i <= n; ++i ){fa[i] = -1;r[i] = 0;ve[i].clear();}}int bch( int x, int y ){int l = 0, r = ve[x].size();while( l <= r ){int mid = ( l + r ) >> 1;if( ve[x][mid] == y ){return mid;}else if( ve[x][mid] > y )r = mid - 1;elsel = mid + 1;}}int dfs( int x ){if( fa[x] == -1 )return x;return fa[x] = dfs( fa[x] );}void merge( int z, int x ){z = dfs( z );x = dfs( x );if( z != x ){if( p[z] > p[x] )fa[x] = z;else if( p[x] > p[z] )fa[z] = x;else{if( z < x )fa[x] = z;elsefa[z] = x;}}}int main(){bool t = 0;while( ~scanf("%d", &n) ){if( t )puts("");t = 1;init();for( int i = 1; i <= n; ++i )scanf("%d", &p[i]);int z, x;scanf("%d", &m);while( m-- ){scanf("%d%d", &z, &x);z++, x++;ve[z].push_back(x);ve[x].push_back(z);}for( int i = 1; i <= n; ++i ){sort( ve[i].begin(), ve[i].end() );}scanf("%d", &q);char op[10];for( int i = 1; i <= q; ++i ){scanf("%s", op);if( op[0] == 'd' ){scanf("%d%d", &a[i].u, &a[i].v);++a[i].u, ++a[i].v;int vv = bch( a[i].u, a[i].v );int uu = bch( a[i].v, a[i].u );int u = a[i].u, v = a[i].v;ve[ u ].erase( ve[ u ].begin() + vv );ve[ v ].erase( ve[ v ].begin() + uu );}else{scanf("%d", &a[i].u);++a[i].u;a[i].v = -1;}}for( int i = 1; i <= n; ++i ){int sz = ve[i].size();for( int j = 0; j < sz; ++j ){merge( i, ve[i][j] );}}for( int i = q; i; --i ){if( a[i].v == -1 ){int ani = dfs( a[i].u );if( p[ani] > p[ a[i].u ] )s.push( ani );elses.push( -1 );}elsemerge( a[i].u, a[i].v );}while( !s.empty() ){if( s.top() != -1 )printf("%d\n", s.top()-1);elseputs("-1");s.pop();}}return 0;}


0 0
原创粉丝点击