Submission #122034

#TimeUsernameProblemLanguageResultExecution timeMemory
122034KLPPDesignated Cities (JOI19_designated_cities)C++14
100 / 100
1830 ms119480 KiB
#include<bits/stdc++.h> using namespace std; typedef long long int lld; typedef pair<lld,lld> pii; #define rep(i,a,b) for(int i=a;i<b;i++) #define trav(a,v) for(auto a:v) #define INF 1000000000000000000 vector<pii> nei[200000]; vector<pii> inv[200000]; set<int> leaves; map<int,lld> tree[200000]; int n; vector<int> V; class ST{ pii arr[1000000]; public: void build(int a, int b, int node){ if(a==b){ arr[node]=pii(0,a); return; } int mid=(a+b)/2; build(a,mid,2*node); build(mid+1,b,2*node+1); arr[node]=min(arr[2*node],arr[2*node+1]); } void update(int a, int b, int node, int pos, lld val){ if(pos<a || b<pos)return; if(a==b){ arr[node]=pii(val,pos); return; } int mid=(a+b)/2; update(a,mid,2*node,pos,val); update(mid+1,b,2*node+1,pos,val); arr[node]=min(arr[2*node],arr[2*node+1]); } int query(){ return arr[1].second; } int query2(){ return arr[1].first; } }; ST *DEG; ST *candidates; void correct(){ while(DEG->query2()==2){ int i=DEG->query(); //cout<<i<<endl; trav(x,tree[i]){ V.push_back(x.first); } //cout<<V[0]<<" "<<V[1]<<endl; lld go=tree[V[0]][i]+tree[i][V[1]]; lld come=tree[V[1]][i]+tree[i][V[0]]; tree[V[0]].erase(tree[V[0]].find(i)); tree[V[1]].erase(tree[V[1]].find(i)); tree[V[0]][V[1]]=go; tree[V[1]][V[0]]=come; DEG->update(0,n-1,1,i,INF); V.clear(); tree[i].clear(); if(leaves.find(V[0])!=leaves.end()){ candidates->update(0,n-1,1,V[0],go); } if(leaves.find(V[1])!=leaves.end()){ candidates->update(0,n-1,1,V[1],come); } } } int view(){ pii best=pii(1000000000000000,-1); trav(l,leaves){ //cout<<l<<endl; pii travel=pii(-1,l); lld ans=0; while(tree[travel.second].size()==2 || travel.first==-1){ //if(travel.first==1)cout<<travel.first<<" "<<travel.second<<" "<<tree[travel.second].size()<<endl; trav(u,tree[travel.second]){ if(travel.first!=u.first){ travel.first=travel.second; travel.second=u.first; ans+=u.second; } } } best=min(best,pii(ans,l)); //cout<<ans<<" "<<l<<endl; } return best.second; } bool visited[200000]; lld size[200000]; lld size2[200000]; void DFS(int node){ visited[node]=true; size[node]=0; trav(p,nei[node]){ if(!visited[p.first]){ DFS(p.first); size[node]+=size[p.first]+p.second; size2[p.first]=-p.second; } } } void DFS2(int node){ visited[node]=true; trav(p,inv[node]){ if(!visited[p.first]){ //cout<<node<<" "<<p.first<<" "<<p.second<<endl; size2[p.first]+=size2[node]+p.second; DFS2(p.first); } } } void print(){ rep(i,0,n){ trav(p,tree[i]){ cout<<p.first<<","<<p.second<<" "; } cout<<endl; } } int main(){ scanf("%d",&n); rep(i,0,n-1){ int x,y; lld z,w; scanf("%d %d %lld %lld",&x,&y,&z,&w); x--;y--; tree[x][y]=w; tree[y][x]=z; nei[x].push_back(pii(y,z)); nei[y].push_back(pii(x,w)); inv[x].push_back(pii(y,w)); inv[y].push_back(pii(x,z)); } DEG=new ST(); candidates=new ST(); DEG->build(0,n-1,1); candidates->build(0,n-1,1); rep(i,0,n){ if(tree[i].size()==1){ leaves.insert(i); candidates->update(0,n-1,1,i,tree[i].begin()->second); DEG->update(0,n-1,1,i,INF); }else{ candidates->update(0,n-1,1,i,INF); DEG->update(0,n-1,1,i,tree[i].size()); } } lld answer[n+1]; rep(i,leaves.size(),n){ answer[i]=0; } correct(); lld ans=0; while(leaves.size()>2){ int u=candidates->query(); pii p=*tree[u].begin(); tree[u].clear(); ans+=p.second; tree[p.first].erase(tree[p.first].find(u)); DEG->update(0,n-1,1,p.first,tree[p.first].size()); correct(); //cout<<tree[0].size()<<endl; //print(); leaves.erase(u); candidates->update(0,n-1,1,u,INF); answer[leaves.size()]=ans; //cout<<ans<<endl; } rep(i,0,n)visited[i]=false; DFS(0); size2[0]=size[0]; rep(i,0,n)visited[i]=false; DFS2(0); answer[1]=size2[0]; rep(i,0,n)answer[1]=min(answer[1],size2[i]); int q; scanf("%d",&q); while(q--){ int x; scanf("%d",&x); printf("%lld\n",answer[x]); } return 0; }

Compilation message (stderr)

designated_cities.cpp: In function 'int main()':
designated_cities.cpp:131:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d",&n);
   ~~~~~^~~~~~~~~
designated_cities.cpp:135:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d %d %lld %lld",&x,&y,&z,&w);
     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
designated_cities.cpp:188:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d",&q);
   ~~~~~^~~~~~~~~
designated_cities.cpp:191:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d",&x);
     ~~~~~^~~~~~~~~
#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...