Submission #982040

#TimeUsernameProblemLanguageResultExecution timeMemory
982040LibSwapping Cities (APIO20_swap)C++14
Compilation error
0 ms0 KiB
#include <bits/stdc++.h> using namespace std; int n,m; vector <vector <int> > InComponents; vector <vector <int> > adj; //the edge list of the KRT vector <int> TVector; int RootID; //ID of the root node of the KRT; struct Edge{ long long Weight; int Start; int End; }; bool operator< (const Edge &x, const Edge &y){ return x.Weight<y.Weight; } Edge Elist[500003]; int Depth[500003]; int Deg[500003]; int CurRep[500003]; //id of the respresentative node on the KRT int Par[500003]; //Parent of node with id i on the KRT; int Toggle[500003]; //is the i-th node on the KRT toggled? int Check[500003]; int Ancestor[500003][20]; long long Val[500003];//the value of the i-th node of the KRT vector <int> KRTID; int GetRep(int u){ if(CurRep[u]==u){ return u; }else{ return CurRep[u]=GetRep[RepU]; } } void DSU(int id, int u, int v, int w){ Deg[u]++; Deg[v]++; //u and v belongs to the same component. The component now has a cycle. Immediately toggle the root node of the current //subtree that includes both u and v on the KRT int RepU=GetRep(u), RepV=GetRep(v); if(RepU==RepV){ //The node isn't toggled just yet. Toggle it immediately if(!Toggle[RepU]){ Toggle[RepU]=1; Val[RepU]=w; }else{ //The node is already toggled by an edge with lower edge. Only a fucking dumbass would touch it - already minimized //toggle value. Just leave it alone } }else{ //u and v doesn't belong to the same component. Merge them int CurID=n-1+id; int OldComp1=RepU, OldComp2=RepV; adj[RepU].push_back(CurID); adj[RepV].push_back(CurID); adj[CurID].push_back(RepU); adj[CurID].push_back(RepV); Par[RepU]=CurID; Par[RepV]=CurID; //if either of the components are toggled already (having a cycle OR a vertex with degree >3) //OR the merged component has a vertex with degree >3 (either u or v), toggle immediately if(Toggle[OldComp1]||Toggle[OldComp2]||Deg[u]>2||Deg[v]>2){ Toggle[CurID]=1; } KRTID.push_back(CurID); RootID=CurID; } } void init(int N, int M, vector <int> U, vector <int> V, vector <int> W){ n=N; m=M; for(int i=0;i<n+m+5;i++){ InComponents.push_back(TVector); adj.push_back(TVector); } for(int i=1;i<=m;i++){ Elist[i].Weight=W[i-1]; Elist[i].Start=U[i-1]; Elist[i].End=V[i-1]; } sort(Elist+1,Elist+m+1); for(int i=0;i<=m+n+1;i++){ CurRep[i]=i; } for(int i=0;i<n;i++){ CurRep[i]=i; InComponents[i].push_back(i); KRTID.push_back(i); } for(int i=1;i<=m;i++){ DSU(i,Elist[i].Start,Elist[i].End,Elist[i].Weight); } //The KRT is now built. BFS from the root node and initialize LCA or something deque <int> dq; dq.push_back(RootID); Check[RootID]=1; int Cur; while(!dq.empty()){ Cur=dq.front(); for(int i=0;i<adj[Cur].size();i++){ if(!Check[adj[Cur][i]]){ dq.push_back(adj[Cur][i]); Check[adj[Cur][i]]=1; Depth[adj[Cur][i]]=Depth[Cur]+1; } } dq.pop_front(); } Par[RootID]=500000; Par[500000]=500000; Toggle[500000]=1; for(int i=0;i<=19;i++){ for(int k=0;k<KRTID.size();k++){ if(i==0){ Ancestor[KRTID[k]][i]=Par[KRTID[k]]; }else{ Ancestor[KRTID[k]][i]=Ancestor[Ancestor[KRTID[k]][i-1]][i-1]; } } } } int getMinimumFuelCapacity(int x, int y){ //I thought that we actually need to use binary lifting to find LCA and then jump from the LCA to find the nearest //toggled node on the KRT //But apparently small-to-large merging ensures that the depth of the tree is always logN or something, so bruteforcing //it is //ok nvm this guy is a fucking moron lmao LogN depth my ass. Wrong analysis, wasted 5 minutes. Fuck me if(Depth[x]<Depth[y]){ swap(x,y); } int JumpLevel=Depth[x]-Depth[y]; for(int i=19;i>=0;i--){ if(JumpLevel >> i & 1){ x=Ancestor[x][i]; } } for(int i=19;i>=0;i--){ if(Ancestor[x][i]!=Ancestor[y][i]){ x=Ancestor[x][i]; y=Ancestor[y][i]; } } x=Par[x]; y=Par[y]; SkipPoint:; if(Toggle[x]){ return Val[x]; } /*int cnt=0; while(!Toggle[Par[x]]&&Par[x]!=500000){ x=Par[x]; }*/ for(int i=19;i>=0;i--){ if(!Toggle[Ancestor[x][i]]){ x=Ancestor[x][i]; } } x=Par[x]; if(Toggle[x]&&x!=500000){ return Val[x]; } return -1; }

Compilation message (stderr)

swap.cpp: In function 'int GetRep(int)':
swap.cpp:30:27: error: 'RepU' was not declared in this scope
   30 |   return CurRep[u]=GetRep[RepU];
      |                           ^~~~
swap.cpp: In function 'void init(int, int, std::vector<int>, std::vector<int>, std::vector<int>)':
swap.cpp:98:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   98 |   for(int i=0;i<adj[Cur].size();i++){
      |               ~^~~~~~~~~~~~~~~~
swap.cpp:111:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  111 |   for(int k=0;k<KRTID.size();k++){
      |               ~^~~~~~~~~~~~~
swap.cpp: In function 'int getMinimumFuelCapacity(int, int)':
swap.cpp:144:2: warning: label 'SkipPoint' defined but not used [-Wunused-label]
  144 |  SkipPoint:;
      |  ^~~~~~~~~