Submission #127637

#TimeUsernameProblemLanguageResultExecution timeMemory
127637OptxPrimeValley (BOI19_valley)C++11
100 / 100
620 ms59044 KiB
#include <iostream> #include <cmath> #include<vector> #include <algorithm> #include <utility> #include<stack> #include<queue> #include<map> #include <fstream> using namespace std; #define pb push_back #define mp make_pair #define ll long long bool color[100010]; vector<int> upd[100010]; bool ispec[100010]; long long dist[100010]; long long dp[100010]; long long inf=100000000000000000; int par[100010][30]; long long path[100010][30]; int lvl[100010]; int n,s,q,e; pair<int,int> edge[100010]; /*struct query{ int color,town,id; query(){} query(int color,int town,int id):color(color),town(town),id(id){} } qlist[100010];*/ struct susjed{ int node,w,id; susjed(){} susjed(int node, long long w,int id):node(node),w(w),id(id){} }; vector<vector<susjed>> adjl; struct result{ int escape; long long minw; }res[100010]; struct in{ int color,town; in(){} in(int color, int town):color(color),town(town){} }qlist[100010]; void dfs( int x, int p, long long len, int depth ) { dist[x] = len; lvl[x]=depth; for( int i=0;i<upd[x].size();i++ ){ int id = upd[x][i]; int c = qlist[ id ].color; // int c = upd[x][i] // int id=upd[x][i].id; res[id].escape = color[c]; /// da li ce pobjec zavisi samo je li dosad naiso na taj color } for( int i=0;i<adjl[x].size();i++ ){ if( adjl[x][i].node==p ) continue; int c = adjl[x][i].id; color[c]=true; /// ukljucimo edge dfs( adjl[x][i].node,x, len + adjl[x][i].w, depth+1 ); color[c]=false; } } void dfs2( int x, int p ) { par[x][0]=p; /// za lca if( ispec[x] ) dp[x]=dist[x]; /// udaljenost od roota else dp[x] = inf; for( int i=0;i<adjl[x].size();i++ ){ if( adjl[x][i].node ==p ) continue; dfs2( adjl[x][i].node, x ); dp[x]=min(dp[x], dp[ adjl[x][i].node ] ); /// minimum od djece } } /* long long lca( int a, int b ) { long long res=inf; if( lvl[a] < lvl[b] ) swap(a,b); int logg; for( logg=0;(1<<logg)<=n;logg++ ); logg--; for( int i=logg;i>=0;i-- ){ if( lvl[a] - ( 1<<i ) >= lvl[b] ) a=par[a][i]; } if( a==b ) return a; for( int i=logg;i>=0;i-- ){ if( par[a][i] !=-1 && par[a][i] != par[b][i] ){ a=par[a][i]; b=par[b][i]; } } return par[a][0]; }*/ /// dzaba kuco lca kad mi ne treva??? samo mi treba bin lifting int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int u,v; long long w; cin>>n>>s>>q>>e; e--; adjl.resize(n); for( int i=0;i<n-1;i++ ){ cin>>u>>v>>w; u--; v--; edge[i] = mp( u,v ); adjl[u].pb( susjed( v,w,i ) ); adjl[v].pb( susjed( u,w,i ) ); } int tmp; vector<int> spec; for( int i=0;i<s;i++ ){ cin>>tmp; tmp--; spec.pb( tmp ); ispec[tmp]=true; } int l,r; for( int i=0;i<q;i++ ){ cin>>l>>r; l--; r--; qlist[i] = in(l,r); upd[r].pb( i ); } for( int j=0;(1<<j)<=n;j++ ){ for( int i=0;i<n;i++ ) par[i][j]= path[i][j]=-1; } ///precalc lca dfs( e,e,0,0 ); /// dfs da offline izracuna samo moze li izaci dfs2( e,e ); /// drugi dfs, racuna lca dp for( int i=0;i<n;i++ ) { if( dp[i]!=inf ) dp[i] -= 2*dist[i]; /// jer dp[i] nam cuva -2*dist[i] + min dist u subtree } /// cini se i ovaj dp dobar /* for( int i = 0;i<n;i++ ){ cout << i << " " << dp[i] << " kontas " <<endl; } for( int i =0;i<n;i++ ){ cout << i << " " << dist[i] << " ee " <<endl; }*/ /// jos ostaje lca da odradimo for(int i=0;i<n;i++) path[i][0]=dp[i]; for( int j=1;(1<<j)<=n;j++ ){ for( int i=0;i<n;i++ ){ if( par[i][j-1]!=-1 ){ par[i][j] = par[ par[i][j-1] ][j-1]; path[i][j] =min( path[i][j-1], path[ par[i][j-1] ][j-1] ); } } } /* for( int i=0;i<n;i++ ){ cout<<par[i][0] << " " << par[i][1] << " " << path[i][0] << " " <<path[i][1] << " blecak " << dp[i]<<endl; }*/ //cout << lca( 2,0 ) << " lekceeaa "<<endl; for( int i=0;i<q;i++ ){ if( res[i].escape == false ){ /// ako nije naisao na edge pokvareni. ovo radi provjerio sam // cout << i <<endl; cout << "escaped"<<endl; } else{ int p; int u=qlist[i].town; long long dd=dist[u]; pair<int,int> ee = edge[ qlist[i].color ]; /// qlist[i].color je index edga if( lvl[ ee.first ] >= lvl[ ee.second ] ) p = ee.first; else p=ee.second; /// ovo je dublji vertex medju dva u kveriju, do njega trazimo minimum long long res=inf; int logg; for( logg =0 ;(1<<logg)<=n;logg++ ); logg--; for( int j=logg;j>=0;j-- ){ if( lvl[u] - (1<<j) >= lvl[p] ){ // cout << i << " " << j << " oko " <<endl; res=min(res, path[u][j] ); u=par[u][j]; } } res=min( res, path[u][0]); if( res!=inf ) cout<<res+dd<<endl; else cout <<"oo"<<endl; // cout << i << " " << p << " " << u << " bruda " <<endl; } } return 0; }

Compilation message (stderr)

valley.cpp: In function 'void dfs(int, int, long long int, int)':
valley.cpp:54:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for( int i=0;i<upd[x].size();i++ ){
                      ~^~~~~~~~~~~~~~
valley.cpp:62:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for( int i=0;i<adjl[x].size();i++ ){
                      ~^~~~~~~~~~~~~~~
valley.cpp: In function 'void dfs2(int, int)':
valley.cpp:75:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for( int i=0;i<adjl[x].size();i++ ){
                      ~^~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...