#include #define ff first #define ss second #define pb push_back #define ll long long using namespace std; typedef pair pii; typedef pair pss; typedef pair psi; /// INIT const int maxn=3e5+10; int n,m; vectorvect[maxn]; vector s; /// INIT END struct dsu{ int n; int cc; vectorp,sz; dsu(int n){ this->n=n; this->cc=n; p.resize(n+1); sz.resize(n+1); for(int i=1;i<=n;i++){ p[i]=i; sz[i]=1; } } void reset(){ for(int i=1;i<=n;i++){ p[i]=i; sz[i]=1; } cc=n; } int root(int x){ if(p[x]==x)return x; return p[x]=root(p[x]); } bool join(int u,int v){ u=root(u); v=root(v); if(u==v)return false; if(sz[u]>sz[v])swap(u,v); p[u]=v; sz[v]+=sz[u]; cc--; return true; } }; ll inf=1e18; int intinf=1e9; struct result{ int n; vector>paths; vectorp; vectorpos; ll score=-1; result(int n){ this->n=n; pos.resize(n,0); } void add_path(vector&v){ paths.pb(v); } void add_to_last_path(int x){ if(paths.size()==0)assert(1==0); paths.back().pb(x); } void new_path(){ paths.pb(vector()); } void assign_p(vectornp){ p=np; } void calc_score(){ if(p.size()!=n){ printf("%d %d AAA\n",p.size(),n); assert(1==0); } for(int i=0;iinf)score=inf; } } if(score>inf/paths.size())score=inf; else score*=paths.size(); } void ispis(){ for(int i=0;i>dp(pw3[n],vector(n,(pii){intinf,intinf})),par(pw3[n],vector(n,(pii){-1,-1})); queue>st[2]; for(int i=0;i(pii){dp[mask][u].ff+w.ff,dp[mask][u].ss+w.ss}){ ///st.erase({dp[nxt][u],{nxt,u} }); dp[nxt][u]={dp[mask][u].ff+w.ff,dp[mask][u].ss+w.ss}; par[nxt][u]={mask,u}; st[0].push({dp[nxt][u],{nxt,u} }); } for(int i=0;i(pii){dp[mask][u].ff+w.ff,dp[mask][u].ss+w.ss}){ //st.erase({dp[nxt][id],{nxt,id} }); dp[nxt][id]={dp[mask][u].ff+w.ff,dp[mask][u].ss+w.ss}; par[nxt][id]={mask,u}; st[1].push({dp[nxt][id],{nxt,id} }); } } } result ret(n); pii curr=end_state; int prvd=-1; while(curr!=(pii){-1,-1}){ if(prvd!=dp[curr.ff][curr.ss].ff)ret.new_path(); ret.add_to_last_path(curr.ss); prvd=dp[curr.ff][curr.ss].ff; curr=par[curr.ff][curr.ss]; } return ret; } namespace bitmask_dp{ short short_inf=30000; template void check_if_have_to_resize(T &a,int n){ if(a.size()recover_path(int mask,short u,vector>>&par){ vectorret; while(mask!=-1){ ret.pb(u); pii pom=par[u][mask]; mask=pom.ss; u=pom.ff; } reverse(ret.begin(),ret.end()); return ret; } vector>> get_non_intersecting_path(vectorstart_points,vectortaken_nodes,int k, vector>>&dp,vector>>&par){ check_if_have_to_resize(dp,n); check_if_have_to_resize(par,n); /*printf("START POINTS\n"); for(int i=0;inode_price(n,1); for(int i=0;iw={-node_price[id],1}; if(dp[id][mask|(1<(pss){dp[i][mask].ff+w.ff,dp[i][mask].ss+w.ss}){ dp[id][mask|(1<>st; for(int mask=(1<=0;mask--){ for(int i=0;ilst)continue; psi pom=(*st.rbegin()).ss; st.insert({dp[i][mask],{i,mask}}); st.erase({lst,pom}); } } vector>>ret; for(auto it=st.begin();it!=st.end();it++){ vectorpath=recover_path((*it).ss.ss,(*it).ss.ff,par); pii pom; pom.ff=(*it).ff.ff; pom.ss=(*it).ff.ss; ret.pb({pom,path}); } return ret; } result solve_with_greedy_bitmasks(){ int max_result=1; vector>>dp; vector>>par; vector,result>>>ret,ret2; vectorsp(n); for(int i=0;itaken_nodes; result pr=ret[i].ss.ss; for(int j=0;j>>paths=get_non_intersecting_path(ret[i].ss.ff,taken_nodes,5,dp,par); //printf("DOSAO222\n"); for(auto path:paths){ pii pom=ret[i].ff; pom.ff+=path.ff.ff; pom.ss+=path.ff.ss; vectorsp; sp.pb(path.ss.back()); pr.add_path(path.ss); ret2.pb({pom,{sp,pr} }); /*printf("%d %d POM\n",pom.ff,pom.ss); for(int j=0;jmax_result)ret2.pop_back(); ret=ret2; } ///printf("%d %d AAAA RET\n",ret[0].ff.ff,ret[0].ff.ss); return ret[0].ss.ss; } } result assign_result(){ result r(n); if(n>11)r=bitmask_dp::solve_with_greedy_bitmasks(); else r=complete_trinary_bitmasks(); return r; } void all_permutations_assignment(result &r){ int fact=1; for(int i=2;i<=n;i++)fact*=i; pair>rez; rez.ff=inf+1; for(int i=0;i>pom; pom.ff=r.score; pom.ss=s; if(r.score>rez; rez.ff=inf+1; for(int i=0;i>pom; pom.ff=r.score; pom.ss=s; if(r.score>rez; rez.ff=inf+1; for(int i=0;i>pom; pom.ff=r.score; pom.ss=s; if(r.score