#include using namespace std; const int nmax=1e5+42; const long long INF=1e18; mt19937 rng(42); int n,m; int s[nmax],id_s=0; int outp[nmax]; bool been[nmax]; vector adj[nmax],path; int deg[nmax]; long long best_score=INF; int best_outp[nmax]; vector< vector > best_paths; void print_paths() { for(int i=1;i<=n;i++)printf("%i ",best_outp[i]); printf("\n"); printf("%i\n",best_paths.size()); for(auto p:best_paths) { printf("%i",p.size()); for(auto cur:p) printf(" %i",cur); printf("\n"); } cerr< adj_for_bfs[nmax]; int deg_bfs[nmax]; pair highest_distance; void dfs_bfs(int node,int par,int d) { if(highest_distance.second in = queue (); int id=0; in.push(root); while(in.size()) { int tp=in.front(); in.pop(); if(been_bfs[tp])continue; for(auto w:adj_for_bfs[tp]) deg_bfs[w]--; been_bfs[tp]=1; id++; outp[tp]=s[id]; sort(adj_for_bfs[tp].begin(),adj_for_bfs[tp].end(),cmp_bfs); for(auto w:adj_for_bfs[tp]) if(been_bfs[w]==0) in.push(w); } } bool in_unique[nmax]; int PARENT[nmax]; int ROOT(int node) { if(PARENT[node]==node)return node; PARENT[node]=ROOT(PARENT[node]); return PARENT[node]; } int order_mini[nmax]; long long actual_min() { sort(outp+1,outp+n+1); long long MINI=1e18; do { long long score=0; for(int i=1;iscore) { MINI=score; for(int i=1;i<=n;i++) order_mini[i]=outp[i]; } } while(next_permutation(outp+1,outp+n+1)); //for(int i=1;i<=n;i++)cerr< longest_path,current_path; void dfs_path(int node,int parent,int target) { current_path.push_back(node); if(node==target) { longest_path=current_path; return; } for(auto w:adj_for_bfs[node]) if(w!=parent) dfs_path(w,node,target); current_path.pop_back(); } int dfs_cnt(int node,int parent,int left_block,int right_block) { if(node==left_block||node==right_block)return 0; int cnt=1; for(auto w:adj_for_bfs[node]) if(w!=parent) cnt+=dfs_cnt(w,node,left_block,right_block); return cnt; } int ID_LONGEST; void bfs_part(int node,set blocked,int add) { queue in = queue (); in.push(node); while(in.size()) { int tp=in.front(); in.pop(); if(outp[tp]!=-1||blocked.count(tp))continue; for(auto w:adj_for_bfs[tp]) deg_bfs[w]--; ID_LONGEST+=add; outp[tp]=s[ID_LONGEST]; sort(adj_for_bfs[tp].begin(),adj_for_bfs[tp].end(),cmp_bfs); for(auto w:adj_for_bfs[tp]) if(outp[w]==-1) in.push(w); } } vector< vector > get_paths() { for(int i=1;i<=n;i++) PARENT[i]=i; for(int i=1;i<=n;i++) adj_for_bfs[i]={}; vector< vector > paths={}; int id_path=0; while(id_path current_path={}; while(id_path > paths=get_paths(); long long cost=0; for(int i=1;i=0)left_block=longest_path[i-1]; int right_block=-1; if(i+1 > by_size={}; for(auto w:adj_for_bfs[longest_path[i]]) if(w!=left_block&&w!=right_block) by_size.push_back({dfs_cnt(w,longest_path[i],longest_path[i],longest_path[i]),w}); sort(by_size.begin(),by_size.end()); reverse(by_size.begin(),by_size.end()); int total=1; for(auto w:by_size) total+=w.first; total=total/2; int total_lower=0; set lower={left_block,right_block},upper={left_block,right_block}; for(auto w:by_size) if(w.first<=total) { lower.insert(w.second); total=total-w.first; total_lower+=w.first; } else upper.insert(w.second); int old_ID=ID_LONGEST; ID_LONGEST=ID_LONGEST+total_lower+2; bfs_part(longest_path[i],upper,-1); ID_LONGEST+=total_lower-1; outp[longest_path[i]]=-1; bfs_part(longest_path[i],lower,1); } cost=0; for(int i=1;i=0)left_block=longest_path[i-1]; int right_block=-1; if(i+1 ordered={}; for(int i=1;i<=n;i++) ordered.push_back(i); sort(ordered.begin(),ordered.end(),cmp_ordered); for(auto i:ordered) { if(1.0*(clock()-T)/CLOCKS_PER_SEC>4.5)break; test(i); } print_paths(); return 0; }