Connections in Galaxy War ZOJ - 3261 离线操作+逆序并查集 并查集删边
Posted qingyuyyyyy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Connections in Galaxy War ZOJ - 3261 离线操作+逆序并查集 并查集删边相关的知识,希望对你有一定的参考价值。
#include<iostream> #include<cstring> #include<stdio.h> #include<map> #include<vector> #define cle(a) memset(a,0,sizeof(a)) using namespace std; const int N=50000+10; int w[20100]; bool cmp(int a,int b){ return a>b; } int n,q,m,fa[N],arr[25000][2],ans[60000]; vector<pair<int,int> >vp; map<pair<int,int>,int>mp; void init(){ for(int i=0;i<=n+5;i++)fa[i]=i; mp.clear(); vp.clear(); cle(ans); cle(arr); } int find(int x){ if(fa[x]!=x) fa[x]=find(fa[x]); return fa[x]; } void Union(int a,int b) { int x=find(a); int y=find(b); if(x==y) return; if(w[x]>w[y]) fa[y]=x; else if(w[x]<w[y]) fa[x]=y; else{ //这里 的判断要注意 if(x<y) fa[y]=x; else fa[x]=y; } } int main() { int mark=0; while(cin>>n) { if(mark) printf(" "); init(); //每个点的价值 for(int i=0;i<n;i++) scanf("%d",&w[i]); scanf("%d",&m); //边 for(int i=1;i<=m;i++) { scanf("%d%d",&arr[i][0],&arr[i][1]); //大的在前面,为后面建边做准备 if(arr[i][0]>arr[i][1]) swap(arr[i][0],arr[i][1]); } scanf("%d",&q); char s[20]; int t,p; for(int i=1;i<=q;i++) { scanf("%s",s); if(s[0]==‘q‘) { scanf("%d",&t); vp.push_back({t,-2}); } else{ scanf("%d%d",&t,&p); if(t>p) swap(t,p); //标记已经建过边了,相当于标记要被拆掉 mp[{t,p}]=1; vp.push_back({t,p}); } } //先把不会被拆掉的边建上 for(int i=1;i<=m;i++) if(!mp[{arr[i][0],arr[i][1]}]) Union(arr[i][0],arr[i][1]); //然后从后往前遍历操作 //如果是查询,直接做 //如果是拆边,就建上 int j=0; for(int i=vp.size()-1;i>=0;i--){ int a=vp[i].first; int b=vp[i].second; //如果是查询 if(b==-2) { //找到父节点 int c=find(a); //如果相同,就是-1 if(w[a]>=w[c]) c=-1; //保存答案 ans[j++]=c; } else Union(a,b); } for(int i=j-1;i>=0;i--) printf("%d ",ans[i]); mark=1; } return 0; }
以上是关于Connections in Galaxy War ZOJ - 3261 离线操作+逆序并查集 并查集删边的主要内容,如果未能解决你的问题,请参考以下文章
ZOJ3261 Connections in Galaxy War —— 反向并查集
题解报告:zoj 3261 Connections in Galaxy War(离线并查集)
Connections in Galaxy War ZOJ - 3261 离线操作+逆序并查集 并查集删边
ZOJ 3261 Connections in Galaxy War (逆向+带权并查集)