Reverse disjoint-set

I - Connections in Galaxy War

Forward This question is very difficult to do, we can start from the reverse.

Forward reverse damage that is bordered edge. Map building when the desired damage while removing, then this figure is the last chart, when faced with damage plus side to side, that is, return to the state before the destruction of the entry side.

The food and outdated ideas like ( D - Supermarket POJ - 1456 ), is also a greedy strategy.

The problem to implement than that dp + weights disjoint-set simpler, mainly used as a map to the key side to prepare for to get rid of the damaged side.

pair can be used as map keys.

ps: 100 multiple lines of code once almost over (pe)

  1 #include <iostream>
  2 #include <cstring>
  3 #include <queue>
  4 #include <map>
  5 #include <stack>
  6 using namespace std;
  7 typedef long long ll;
  8 const int maxn=10005;
  9 ll cnt[maxn];int f[maxn];
 10 struct node{
 11     char s[10];
 12     int a,b;
 13 }Q[5*maxn];//不用更新 
 14 struct edge{
 15     int a,b;
 16 }e[maxn*2];//不用更新 
 17 int n,m,q;
 18 map< pair<int,int>,int> M;
 19 void read(){
 20     cin>>n;
 21     for(int i=0;i<n;i++)
 22         cin>>cnt[i];
 23     cin>>m;
 24     for(int i=1;i<=m;i++){
 25         int a,b;cin>>a>>b;
 26         if(a>b) swap(a,b);
 27         e[i].a=a;e[i].b=b;
 28     }
 29     cin>>q;
 30     for(int i=1;i<=q;i++){
 31         cin>>Q[i].s;if(Q[i].s[0]=='q') cin>>Q[i].a;
 32             else{
 33                 cin>>Q[i].a>>Q[i].b;
 34                 if(Q[i].a>Q[i].b) swap(Q[i].a,Q[i].b);
 35                 pair <int,int> P;
 36                 P=make_pair(Q[i].a,Q[i].b);
 37                 M[P]=1;
 38             }
 39     }
 40 }
 41 void init(){
 42     M.clear();
 43     for(int i=0;i<=n;i++){
 44         f[i]=i;cnt[i]=0;
 45     }
 46 }
 47 
 48 int find(int x){
 49     if(x!=f[x])
 50     {
 51         f[x]=find(f[x]);
 52     }
 53     return f[x];
 54 }
 55 
 56 void uniont(int a,int b){
 57     int fa=find(a);int fb=find(b);
 58     if(cnt[fa]>cnt[fb])
 59     {
 60         f[fb]=fa;
 61     }else if(cnt[fa]==cnt[fb]){
 62         if(fa<fb)    f[fb]=fa;
 63             else    f[fa]=fb;
 64     }else
 65     {
 66         f[fa]=fb;
 67     }
 68 }
 69 
 70 void build(){
 71     for(int i=1;i<=m;i++){
 72         pair<int,int> P;
 73         P=make_pair(e[i].a,e[i].b);
 74         if(M.count(P)) continue;
 75         else
 76         {
 77             uniont(e[i].a,e[i].b);
 78         }
 79     }
 80 }
 81 
 82 void solve(){
 83     stack <ll> ans;
 84     for(int i=q;i>=1;i--){
 85         if(Q[i].s[0]=='q')
 86         {
 87             int a=Q[i].a;
 88             int fa=find(a);
 89             if(cnt[fa]<=cnt[a]) ans.push(-1);
 90                 else ans.push(fa);
 91         }else
 92         {
 93             int a=Q[i].a;int b=Q[i].b;
 94             uniont(a,b);
 95         }
 96     }
 97     while(!ans.empty())
 98     {
 99         cout <<ans.top()<<"\n";
100         ans.pop();
101     }
102 }
103 int main(){
104     init();int cas=1;
105     std::ios::sync_with_stdio(false);
106     while(cin>>n){
107         if(cas!=1) cout <<"\n";
108         cas++;
109         init();    
110         for(int i=0;i<n;i++)
111             cin>>cnt[i];
112         cin>>m;
113         for(int i=1;i<=m;i++){
114             int a,b;cin>>a>>b;
115             if(a>b) swap(a,b);
116             e[i].a=a;e[i].b=b;
117         }
118         cin>>q;
119         for(int i=1;i<=q;i++){
120             cin>>Q[i].s;
121             if(Q[i].s[0]=='q') cin>>Q[i].a;
122                 else{
123                     cin>>Q[i].a>>Q[i].b;
124                     if(Q[i].a>Q[i].b) swap(Q[i].a,Q[i].b);
125                     pair <int,int> P;
126                     P=make_pair(Q[i].a,Q[i].b);
127                     M[P]=1;
128                 }
129         }
130         build();solve();
131     }
132     return 0;
133 }

 

Guess you like

Origin www.cnblogs.com/Msmw/p/11262568.html