1. 程式人生 > >ZOJ 3261 Connections in Galaxy War (逆向+帶權並查集)

ZOJ 3261 Connections in Galaxy War (逆向+帶權並查集)

std 合並 clas n) turn typedef algorithm urn print

題意:有N個星球,每個星球有自己的武力值。星球之間有M條無向邊,連通的兩個點可以相互呼叫支援,前提是對方的武力值要大於自己。當武力值最大的夥伴有多個時,選擇編號最小的。有Q次操作,destroy為切斷連接兩點的邊,query為查詢某星球能不能向它人呼叫支援。

還是需要離線逆向並查集求解。思路和HDU 4496很相似,但是此處不一定是把所有邊都刪去,所以需要刪邊的情況建立出最終的狀態。因為N可以到1e4,所以可以用map嵌套map的方式記錄過程中被刪去的邊,最後再根據刪除情況建立狀態。

在合並時需要維護自己能夠申請到的支援的武力最大值,以及其編號。

 1 #include<stdio.h>
 2
#include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<cmath> 6 #include<map> 7 using namespace std; 8 typedef long long LL; 9 const int maxn = 2e4+5; 10 const int INF= 0x3f3f3f3f; 11 struct Edge{ 12 int u,v; 13 }E[maxn]; 14 struct Query{ 15 int
op,a,b; 16 LL ans; 17 }p[maxn*3]; 18 LL w[maxn]; 19 LL dist[maxn]; 20 int fa[maxn]; 21 int maxid[maxn]; 22 inline int Find(int x) {return fa[x]==x ?x: fa[x]=Find(fa[x]);} 23 //void init(int N){ for(int i=0;i<N;++i) fa[i]=i,dist[i]=w[i],maxid[i]=i;} 24 void Union(int a,int b){ 25 a = Find(a),b = Find(b);
26 if(a!=b){ 27 fa[a] = b; 28 if(dist[b]<dist[a] || dist[b]==dist[a] && maxid[b]>maxid[a]){ 29 dist[b]=dist[a]; 30 maxid[b]= maxid[a]; 31 } 32 } 33 } 34 35 map<int,map<int,int> > tag; 36 37 int main() 38 { 39 #ifndef ONLINE_JUDGE 40 freopen("in.txt","r",stdin); 41 freopen("out.txt","w",stdout); 42 #endif 43 int T,N,M,Q,u,v,tmp,K,cas=1; 44 char op[10]; 45 int mk = 0; 46 while(scanf("%d",&N)==1){ 47 if(mk) printf("\n"); 48 mk = 1; 49 for(int i=0;i<N;++i) { 50 scanf("%lld",&w[i]); 51 fa[i]=maxid[i]=i; 52 dist[i]=w[i]; 53 } 54 tag.clear(); 55 scanf("%d",&M); 56 for(int i=1;i<=M;++i){ 57 scanf("%d%d",&u,&v); 58 E[i].u =u , E[i].v=v; 59 } 60 scanf("%d",&Q); 61 for(int i=1;i<=Q;++i){ 62 scanf("%s%d",op,&p[i].a); 63 if(op[0]==d) { 64 p[i].op=0; 65 scanf("%d",&p[i].b); 66 tag[p[i].a][p[i].b]=tag[p[i].b][p[i].a]=1; //被刪邊的標記 67 } 68 else p[i].op = 1; //0刪邊,1查詢 69 } 70 //因為並不是把邊全刪完,建立最終狀態 71 for(int i=1;i<=M;++i){ 72 if(tag[E[i].u][E[i].v]) continue; //這條邊不在 73 else Union(E[i].u,E[i].v); 74 } 75 76 for(int i=Q;i>=1;--i){ 77 if(!p[i].op) Union(p[i].a,p[i].b); 78 else{ 79 u = Find(p[i].a); 80 if(dist[u]>w[p[i].a]) p[i].ans=maxid[u]; 81 else p[i].ans= -1; 82 } 83 } 84 for(int i=1;i<=Q;++i){ 85 if(p[i].op) printf("%lld\n",p[i].ans); 86 } 87 } 88 return 0; 89 }

ZOJ 3261 Connections in Galaxy War (逆向+帶權並查集)