Submission #1162989

#TimeUsernameProblemLanguageResultExecution timeMemory
1162989tosivanmakTowns (IOI15_towns)C++20
25 / 100
9 ms584 KiB
#include<bits/stdc++.h> #include "towns.h" using namespace std; #define ll long long struct DSU{ vector<ll>fa,siz; void init(ll n){ fa.resize(n+5); siz.resize(n=5); } ll root(ll x){ if(fa[x]==x)return x; return fa[x]=root(fa[x]); } void unite(ll u, ll v){ u=root(u); v=root(v); if(siz[u]<siz[v])swap(u,v); siz[u]+=siz[v]; fa[v]=u; } }; bool asked[150][150]; ll dist[150][150]; int get(int i, int j){ if(i==j){ dist[i][j]=0; asked[i][j]=1; return dist[i][j]; } if(asked[i][j]){ return dist[i][j]; } dist[i][j]=dist[j][i]=getDistance(i,j); asked[i][j]=asked[j][i]=1; return dist[i][j]; } int hubDistance(int N, int sub){ // getDistance(i, j) for(int i=0;i<150;i++){ for(int j=0;j<150;j++){ asked[i][j]=0; } } ll initial[150]; for(int i=0;i<N;i++){ initial[i]=get(0,i); } ll fur=-1,nd=-1; for(int i=0;i<N;i++){ if(initial[i]>fur){ fur=initial[i]; nd=i; } } ll dia[150]; for(int i=0;i<N;i++){ dia[i]=get(nd,i); } ll fur2=-1,nd2=-1; for(int i=0;i<N;i++){ if(dia[i]>fur2){ fur2=dia[i]; nd2=i; } } // nd,nd2 forms the diameter // how far away from nd ll dep[155]; dep[nd]=0; dep[nd2]=0; ll diameter=get(nd,nd2); dep[0]=get(0,nd)+get(0,nd2)-diameter; dep[0]/=2; ll fromnd=get(0,nd)-dep[0]; ll fromnd2=get(0,nd2)-dep[0]; for(int i=1;i<N;i++){ ll diff=get(0,i)+get(i,nd)-get(0,nd); ll req=(diff+2*fromnd); // if(req==2*get(nd,i)){ // // closer to nd2 // dep[i]=(get(nd2,i)+get(nd,i)-diameter)/2; // } // else{ // ll tryy=diff/2; // ll chn=get(i,nd)-tryy; // if(chn>fromnd){ // chn=get(0,nd)-dep[0]; // dep[i]=get(i,nd)-chn; // } // else{ // dep[i]=tryy; // } // } dep[i]=(get(nd2,i)+get(nd,i)-diameter)/2; } vector<ll>dists; for(int i=0;i<N;i++){ dists.push_back(get(nd,i)-dep[i]); } sort(dists.begin(),dists.end()); dists.erase(unique(dists.begin(),dists.end()),dists.end()); ll ans=1e18; vector<ll>cand; for(int i=0;i<dists.size();i++){ ll val=max(dists[i],diameter-dists[i]); if(val<ans){ cand.clear(); ans=val; cand.push_back(dists[i]); } else if(val==ans){ cand.push_back(dists[i]); } } return ans; for(auto& u: cand){ ll cnt=0; for(int i=0;i<N;i++){ if(dists[i]==u){ cnt++; } } ll smol=0,lar=0; if(cnt<=N/2){ // no checking for(int i=0;i<N;i++){ if(dists[i]<u)smol++; else lar++; } if(smol<=N/2&&lar<=N/2)return ans; else return -ans; } else{ // since cnt > N/2 others <= N/2 vector<ll>req; req.push_back(0); for(int i=0;i<N;i++){ if(dists[i]==u)req.push_back(i); } DSU d; d.init(req.size()); bool used[req.size()+5]; for(int i=0;i<req.size()+5;i++)used[i]=0; ll ptrl=1,ptrr=1; while(ptrr<req.size()){ if(ptrl==ptrr){ptrr++; continue;} if(used[ptrr]){ptrr++; continue;} if(used[ptrl]){ptrl++; continue;} ll dt=get(req[ptrl],req[ptrr]); ll real=dep[req[ptrl]]+dep[req[ptrr]]; if(real==dt){ used[ptrl]=used[ptrr]=1; ptrl++; ptrr++; } else{ d.unite(used[ptrl],used[ptrr]); ptrr++; } } ll id=-1; for(int i=1;i<req.size();i++){ if(!used[i]){ id=i; break; } } if(id==-1){ return ans; } for(int i=1;i<req.size();i++){ if(d.root(i)!=d.root(id)&&d.root(i)==i){ ll dt=get(req[i],req[id]); ll real=dep[req[id]]+dep[req[i]]; if(dt!=real){ d.unite(i,id); } } } if(d.siz[d.root(id)]<=N/2)return ans; else return -ans; } } return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...