zoj 3261 逆向并查集

很明显是逆向的并查集,建立边再销毁,思路也很巧妙的逆向思考~

如果正着一一销毁,相当于倒着一一建边。

所以保存Q次提问,最后倒着来一一建边。

在此之前先把没有销毁的边全部建好~细节power能量注意一下~

View Code
 1 #include <map>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <vector>
 5 #include <iostream>
 6 using namespace std;
 7 
 8 const int N=50005;
 9 int n,m,i,j;
10 int power[N];
11 int father[N];
12 int g[N][3];
13 int ans[N],cnt;
14 map<pair<int,int>,int>M;
15 
16 int find(int x){
17     if(x!=father[x]){
18         father[x]=find(father[x]);
19     }
20     return father[x];
21 }
22 
23 void merge(int a,int b){
24     int x=find(a);
25     int y=find(b);
26     if(x==y) return ;
27     if(power[x]>power[y]||(power[x]==power[y]&&x<y)) father[y]=x;
28     else father[x]=y;
29 }
30 int main(){
31     char ch[10];
32     int a,b,q,k=0;
33     while(scanf("%d",&n)!=EOF){
34         M.clear();
35         for(i=0;i<n;i++)
36             scanf("%d",&power[i]),
37             father[i]=i;
38 
39         scanf("%d",&m);
40         for(i=0;i<m;i++){
41             scanf("%d%d",&a,&b);
42             if(a>b) a^=b^=a^=b;
43             M[make_pair(a,b)]=1;
44         }
45 
46         scanf("%d",&q);
47         for(i=0;i<q;i++){
48             scanf("%s",ch);
49             if(ch[0]=='q'){
50                 scanf("%d",&a);
51                 g[i][0]=0;
52                 g[i][1]=a;
53             }else{
54                 scanf("%d%d",&a,&b);
55                 g[i][0]=1;
56                 g[i][1]=a;
57                 g[i][2]=b;
58                 if(a>b) a^=b^=a^=b;
59                 M[make_pair(a,b)]=0;
60             }
61         }
62 
63         map<pair<int,int>,int>::iterator it;
64         for(it=M.begin();it!=M.end();it++){
65             if(it->second){
66                 pair<int,int> tmp=it->first;
67                 merge(tmp.first,tmp.second);
68             }
69         }
70         cnt=0;
71         while(q--){
72             if(g[q][0]){
73                 merge(g[q][1],g[q][2]);
74             }else{
75                 a=g[q][1];
76                 int x=find(a);
77                 if(power[x]==power[a]) ans[cnt++]=-1;
78                 else ans[cnt++]=x;
79             }
80         }
81         if(k++) puts("");
82         while(cnt--)
83             printf("%d\n",ans[cnt]);
84     }
85     return 0;
86 }

 

posted @ 2013-02-07 03:53  _sunshine  阅读(203)  评论(0编辑  收藏  举报