Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "fun.h"
- #include<bits/stdc++.h>
- using namespace std;
- typedef vector<int> vi;
- typedef pair<int,int> pi;
- typedef vector<pi> vpi;
- #define pb emplace_back
- #define mp make_pair
- #define f first
- #define s second
- #define ALL(x) x.begin(),x.end()
- #define SZ(x) (int)x.size()
- const int MAXN= 100100;
- vi res;
- vpi V[MAXN]; // pair(distance, node). Length is 0 for all nodes except neighbours of centroid
- int pd[MAXN]; // distance from centroid
- int mid3[MAXN]; // exclude the centroid + neighbours
- int belg[MAXN]; // which subtree a node belongs to
- std::vector<int> createFunTour(int N, int Q) {
- int rt=0;
- vpi T;
- for(int i=1;i<N;++i){
- T.pb(mp(attractionsBehind(0,i),i));
- }
- sort(ALL(T));reverse(ALL(T));
- while(T.size()&&T.back().f<=N/2)T.pop_back();
- int cent=rt;
- if(SZ(T)==0)cent=rt;
- else{
- cent=T.back().s;
- }
- belg[cent]=-1;
- vi adj;
- for(int i=0;i<N;++i){
- int d=hoursRequired(cent,i);
- pd[i]=d;
- if(d==1){
- adj.pb(i);
- mid3[i]=1;
- }
- }
- mid3[cent]=1;
- assert(SZ(adj)<=3);
- for(int i=0;i<N;++i)if(!mid3[i]){
- int done=0;
- for(auto x:adj)if(x!=adj.back()){
- int k=hoursRequired(x,i);
- if(k==pd[i]-1){
- V[x].pb(mp(pd[i],i));
- done=1;
- break;
- }
- }
- if(!done)V[adj.back()].pb(mp(pd[i],i));
- }
- for(auto i:adj){
- V[i].pb(mp(pd[i],i));
- sort(ALL(V[i]));
- }
- for(auto i:adj)for(auto j:V[i]){
- belg[j.s]=i;
- }
- int blk=-1;
- int LFT=N;
- while(SZ(res) < N){
- int skip=0;
- int biggst=adj[0];
- for(auto i:adj)if(SZ(V[i]) > SZ(V[biggst]))biggst=i;
- int rst=LFT-SZ(V[biggst]);
- int tx=SZ(V[biggst]);
- if(tx==rst)skip=1;
- if(skip){ // Dominant case
- int MAJ=adj[0];
- for(auto i:adj)if(SZ(V[i]) > SZ(V[MAJ]))MAJ=i;
- if(blk!=MAJ){
- pi t=mp(-1,-1);
- for(auto i:adj)if(i!=blk){
- if(SZ(V[i])){
- pi x=V[i].back();
- t=max(t,x);
- }
- }
- if(t.s!=MAJ && t.f!=-1 && SZ(res) && pd[res.back()] < t.f){
- // Swap over to other, taller small branch
- res.pb(t.s);
- V[belg[t.s]].pop_back();
- blk=-1;
- }
- }
- vpi rest;
- for(auto i:adj)if(i!=MAJ){
- for(auto k:V[i])rest.pb(k);
- }
- rest.pb(-1,cent);
- sort(ALL(rest));
- while(SZ(res)<N){
- if(blk==MAJ){
- blk=-1;
- res.pb(rest.back().s);
- rest.pop_back();
- }else{
- res.pb(V[MAJ].back().s);
- V[MAJ].pop_back();
- blk=MAJ;
- }
- }
- return res;
- }
- else{ // Greedily go to bigest branch that is not currently visited
- int furtbst=-1;
- int t=-1;
- int tp=-1;
- for(auto i:adj)if(SZ(V[i])){
- if(i==blk)continue;
- int k=V[i].back().s;
- int cd=V[i].back().f;
- if(cd>=furtbst){
- furtbst=cd;
- t=k;
- tp=i;
- }
- }
- if(t==-1){
- res.pb(cent);
- assert(SZ(res)==N);
- return res;
- }
- blk=tp;
- res.pb(t);
- V[tp].pop_back();
- }
- --LFT;
- }
- return res;
- }
Advertisement
Add Comment
Please, Sign In to add comment