Guest User

Shrines setter solution

a guest
Apr 12th, 2021
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.24 KB | None | 0 0
  1. // Alei's submission
  2. #include<bits/stdc++.h>
  3. const bool TESTING=false;
  4. using namespace std;
  5. typedef long long int uli;
  6. const int mxn=333;
  7. int d[mxn][mxn];
  8. map<pair<int,int>, pair<int,int> >mp;
  9. vector<vector<int> >g;
  10. vector<int>ans;
  11. vector<int>holy;
  12. int N, V, K, M, C, E;
  13. int nqs=0;
  14. pair<int,int>ask(int u,int v){
  15.   if(mp.count({u,v}))return mp[{u,v}];
  16.   nqs++;
  17.   assert(nqs<=C);
  18.  
  19.   cout<<1<<" "<<u+1<<" "<<v+1<<endl;
  20. //  cerr<<"nqs="<<nqs<<" C="<<C<<endl;
  21.   int x,y;
  22.   if(TESTING){
  23.     x = 0, y = 0;
  24.     for (int i = 0; i < K; i++){
  25.       if (d[i][u] < d[i][v]) x++;
  26.       if (d[i][v] < d[i][u]) y++;
  27.     }
  28.   }
  29.   else{
  30.     cin>>x>>y;
  31.   }
  32.   mp[{u,v}]={x,y};
  33.   mp[{v,u}]={y,x};
  34. //  cerr<<" ans="<<x<<";"<<y<<endl;
  35.   return {x,y};
  36. }
  37. void answer(){
  38.   cout<<2<<" "<<ans.size();
  39.   sort(ans.begin(),ans.end());
  40.   for(int x:ans)cout<<" "<<x+1;
  41.   cout<<endl;
  42.  
  43.   if(TESTING){
  44.     if(ans!=holy){
  45.       cerr<<"wtf!"<<endl;
  46.       cerr<<"ans=";for(int x:ans)cout<<x<<" ";cout<<endl;
  47.       cerr<<"holy=";for(int x:holy)cout<<x<<" ";cout<<endl;
  48.     }
  49.     assert(ans==holy);
  50.   }
  51. }
  52. void findDual(vector<set<int> >&adj){
  53.   vector<vector<int> >cities;  
  54.   vector<pair<int,int> >petals;
  55.   vector<vector<int> >contours;
  56.   for(int i=0;i<N+N;i++){
  57.     int j=(i+1)%(N+N);
  58.     petals.push_back({i,j});
  59.     contours.push_back({i,j});
  60.   }
  61.   while(true){
  62.     if(petals.size()<=2){
  63.       for(auto c:contours){
  64.         cities.push_back(c);
  65.       }
  66.       break;
  67.     }
  68.  
  69.     bool change=false;
  70.     int sz=petals.size();
  71.     /*
  72.        for(int i=0;i<int(petals.size());i++){
  73.        cerr<<"petal "<<petals[i].first<<";"<<petals[i].second<<": ";
  74.        for(int x:contours[i])cerr<<x<<" ";cerr<<endl;
  75.        }
  76.        */
  77.     for(int i=0;i<sz;i++){
  78.       int j=(i+1)%sz;
  79.       int u=petals[i].second;
  80.       if(adj[u].empty()){
  81.         pair<int,int>petal={petals[i].first,petals[j].second};
  82.         auto contour=contours[i];
  83.         assert(contours[j][0]==u);
  84.         for(int x:contours[j])if(x!=u)contour.push_back(x);
  85.         petals.erase(petals.begin()+i);
  86.         contours.erase(contours.begin()+i);
  87.  
  88.         petals[i%petals.size()]=petal;
  89.         contours[i%petals.size()]=contour;
  90.         change=true;
  91.         break;
  92.       }
  93.     }
  94.     if(change)continue;
  95.     for(int i=0;i<sz;i++){
  96.       int u=petals[i].first;
  97.       int v=petals[i].second;
  98.       if(adj[u].count(v)){      
  99.         adj[u].erase(v);
  100.         adj[v].erase(u);
  101.         cities.push_back(contours[i]);
  102.  
  103.         contours[i]={u,v};
  104.         change=true;
  105.         break;
  106.       }
  107.     }
  108.     if(change)continue;
  109.  
  110.     int u,v,w=-1;
  111.     int at=-1;
  112.  
  113.     for(int i=0;i<sz && w==-1;i++){
  114.       u=petals[i].first;
  115.       v=petals[i].second;
  116.       for(int x:adj[u]){
  117.         if(adj[v].count(x)){
  118.           w=x;
  119.           at=i;
  120.           break;
  121.         }
  122.       }
  123.     }
  124.     assert(w!=-1);    
  125.     auto city=contours[at];
  126.     city.push_back(w);
  127.     cities.push_back(city);
  128.  
  129.     assert(w!=-1);
  130.     int lft=(at-1+sz)%sz;
  131.     int rht=(at+1)%sz;
  132.     int z=petals[lft].second;
  133.     adj[z].erase(w);
  134.     adj[w].erase(z);
  135.  
  136.     petals[at]={z,w};
  137.     contours[at]={z,w};
  138.  
  139.     z=petals[rht].first;
  140.     adj[z].erase(w);
  141.     adj[w].erase(z);
  142.  
  143.     petals.insert(petals.begin()+at+1,{w,z});
  144.     contours.insert(contours.begin()+at+1,{w,z});
  145.   }
  146.   sort(cities.begin(),cities.end());
  147. /*
  148.   cerr<<"cities"<<endl;
  149.   for(auto c:cities){
  150.     for(int x:c)cerr<<x+1<<" ";cerr<<endl;
  151.   }
  152. */
  153.  
  154.   int c=cities.size();
  155.   vector<int>o(c);
  156.   iota(o.begin(),o.end(),0);
  157.   vector<vector<int>>sorted;
  158.  
  159.   for(vector<int>c : cities){
  160.     sort(c.begin(),c.end());
  161.     for(int i=1;i<int(c.size());i++)assert(c[i]>c[i-1]);
  162.     sorted.push_back(c);
  163.   }
  164.   sort(o.begin(),o.end(),[&sorted](int i,int j)->bool{
  165.       return sorted[i]<sorted[j];
  166.       });
  167.   vector<int>index(c);
  168.   for(int i=0;i<c;i++){
  169.     index[o[i]]=i;
  170.   }
  171.   map<pair<int,int>,set<int> >mapa;
  172.   for(int it=0;it<c;it++){
  173.     auto c=cities[it];
  174.     int cnt=c.size();
  175.     for(int i=0;i<cnt;i++){
  176.       int u=c[i];
  177.       int v=c[(i+1)%cnt];
  178.       if(u>v)swap(u,v);
  179.       mapa[{u,v}].insert(index[it]);
  180.     }
  181.   }
  182.   g.clear();
  183.   g.resize(c);
  184.   for(auto p:mapa){
  185.     assert(p.second.size()<=2);
  186.     if(p.second.size()==2){
  187.       int u=*p.second.begin();
  188.       int v=*p.second.rbegin();
  189.       g[u].push_back(v);
  190.       g[v].push_back(u);
  191.     }
  192.   }
  193.   C=c;
  194.   assert(c<=300);
  195.   assert(2<=K && K<=C);
  196. }
  197.  
  198. void pre(){
  199.   assert(int(g.size())==C);
  200.   vector<vector<int> >h(C);
  201.   for(int i=0;i<E;i++){
  202.     int u,v;
  203.     cin>>u>>v;
  204.     h[--u].push_back(--v);
  205.     h[v].push_back(u);
  206.   }
  207.   for(int i=0;i<C;i++){
  208.     sort(g[i].begin(),g[i].end());
  209.     sort(h[i].begin(),h[i].end());
  210.     assert(g[i]==h[i]);
  211.   }
  212.   assert(g==h);
  213.   //bfs from gods home
  214.   for (int i = 0; i < K; i++){
  215.     int u;
  216.     cin>>u;
  217.     assert(1<=u&&u<=C);
  218.     --u;
  219.     for (int j = 0; j < C; j++) d[i][j] = -1;
  220.     d[i][u] = 0;
  221.     queue <int> q;
  222.     q.push(u);
  223.     while (!q.empty()){
  224.       u = q.front();
  225.       q.pop();
  226.       for (int v : g[u]){
  227.         if (d[i][v] == -1){
  228.           d[i][v] = d[i][u] + 1;
  229.           q.push(v);
  230.         }
  231.         else assert(d[i][v]<=d[i][u]+1);
  232.       }
  233.     }
  234.  
  235.     for (int j = 0; j < C; j++) assert(d[i][j]>=0);
  236.   }
  237.   //find holy cities
  238.   int mini = 1e9;
  239.   holy.clear();
  240.   for (int u = 0; u < C; u++){
  241.     int sm = 0;
  242.     for (int i = 0; i < K; i++){
  243.       sm += d[i][u];
  244.     }
  245.     if (sm == mini){
  246.       holy.push_back(u);
  247.     }
  248.     else if(sm < mini){
  249.       mini = sm;
  250.       holy = {u};
  251.     }
  252.   }
  253.   assert(mini<1e9);
  254.   sort(holy.begin(),holy.end());
  255. }
  256. int main(){
  257.   int t;
  258.   cin>>t;
  259.   int sm=0;
  260.   for(int tt=0;tt<t;tt++){
  261.     cin>>N>>V>>M>>K;
  262. //    assert(K==2);
  263.     if(TESTING)cin>>C>>E;
  264.  
  265.     vector<set<int> >adj(V);
  266.     for(int i=0;i<M;i++){
  267.       int u,v;
  268.       cin>>u>>v;
  269.       assert(1<=u&&u<=V);
  270.       assert(1<=v&&v<=V);
  271.       adj[--u].insert(--v);
  272.       adj[v].insert(u);
  273.     }
  274.     findDual(adj);
  275.     sm+=C;
  276.     assert(sm<=1e4);
  277.     if(TESTING)pre();
  278.     mp.clear();
  279.     nqs=0;
  280.     int u=0;
  281.     vector<bool>vis(C);
  282.     vector<int>parent(C,-1);
  283.     vis[u]=true;
  284.     parent[u]=u;
  285.     int old=-1;
  286.     while(old!=u){
  287.       old=u;
  288.       for(int v:g[u]){
  289.         if(!vis[v]){
  290.           auto p=ask(v,u);
  291.           int x=p.first;
  292.  
  293.           if(x+x>=K){
  294.             vis[v]=true;
  295.             parent[v]=u;
  296.             u=v;
  297.             break;
  298.           }
  299.         }
  300.       }
  301.     }
  302.     queue<int>q;
  303.     q.push(u);
  304.     fill(vis.begin(),vis.end(),false);
  305.     vis[u]=true;
  306.     ans.clear();
  307.     ans.push_back(u);
  308.  
  309.     while(u!=parent[u]){
  310.       auto qry=ask(parent[u],u);
  311.       int x=qry.first;
  312.       u=parent[u];
  313.       if(x+x>=K){
  314.         q.push(u);
  315.         vis[u]=true;
  316.         ans.push_back(u);
  317.       }
  318.       else break;
  319.     }
  320.     u=q.front();
  321.     while(u!=parent[u]){
  322.       u=parent[u];
  323.       vis[u]=true;
  324.     }
  325.  
  326.     while(!q.empty()){
  327.       u=q.front();
  328.       q.pop();
  329.       for(int v:g[u]){
  330.         if(vis[v])continue;
  331.         vis[v]=true;
  332.         auto p=ask(v,u);
  333.         int x=p.first;
  334.         if(x+x>=K){
  335.           vis[v]=true;
  336.           ans.push_back(v);
  337.           q.push(v);
  338.         }
  339.       }
  340.     }
  341.     answer();
  342.   }
  343.   return 0;
  344. }
  345.  
Add Comment
Please, Sign In to add comment