Submission #100153

#TimeUsernameProblemLanguageResultExecution timeMemory
100153aleksamEvacuation plan (IZhO18_plan)C++14
100 / 100
950 ms30164 KiB
//IZHO 2018 P2 #include <bits/stdc++.h> #define INF INT_MAX #define MOD 100000007 #define MAX_N 100000 #define MAX_M 100000 #define MAX_Q 100000 using namespace std; struct edge{ int d; int w; }; struct dj{ int v; int p; public: bool operator<(const dj& rhs) const{ return p>rhs.p;//Jer priroty queue vraca obrnuto } }; int N, M; vector<edge> adj[MAX_N]; int height[MAX_N]; int query[MAX_Q][2]; int K, Q; bool npp[MAX_N]; void input(){ cin>>N>>M; for(int i=0; i<M; ++i){ int a, b, w; cin>>a>>b>>w; a--; b--; edge ea, eb; ea.d=b; eb.d=a; ea.w=eb.w=w; adj[a].push_back(ea); adj[b].push_back(eb); } cin>>K; memset(npp, 0, sizeof(npp)); for(int i=0; i<K; ++i){ int g; cin>>g; g--; npp[g]=1; } } priority_queue<dj> pq; void relax(int v){ int d=adj[v].size(); for(int i=0; i<d; ++i){ int u=adj[v][i].d; int l=adj[v][i].w; if(height[u]>height[v]+l){ height[u]=height[v]+l; dj un; un.p=height[u]; un.v=u; pq.push(un); } } } void find_height(){ memset(height, INF, sizeof(height)); for(int i=0; i<N; ++i){ if(npp[i]){ height[i]=0; } else height[i]=INF; } for(int i=0; i<N; ++i){ if(npp[i])relax(i); } while(!pq.empty()){ int v=pq.top().v; pq.pop(); if(npp[v])continue; relax(v); npp[v]=1; } } int p[MAX_N], rk[MAX_N]; dj vert[MAX_N]; int pt[MAX_N], inv[MAX_N]; int anc[MAX_N][20]; int depth[MAX_N]; void unionfindinit(){ for(int i=0; i<N; ++i){ p[i]=i; } } int find(int a){ if(a!=p[a])p[a]=find(p[a]); return p[a]; } bool cmp(dj a, dj b){ return a.p>b.p; } void maketree(){ for(int i=0; i<N; ++i){ vert[i].v=i; vert[i].p=height[i]; } sort(vert, vert+N, cmp); memset(pt, -1, sizeof(pt)); for(int i=0; i<N; ++i){ inv[vert[i].v]=i; } for(int i=0; i<N; ++i){ int v=vert[i].v; int d=adj[v].size(); for(int j=0; j<d; ++j){ int u=adj[v][j].d; int fu=find(u); if(inv[u]<inv[v] && fu!=v && pt[fu]==-1){ u=fu; pt[u]=v; p[u]=v; } } } /*for(int i=0; i<N; ++i){ printf("inv[%d]=%d\n", i, inv[i]); } for(int i=0; i<N; ++i){ printf("pt[%d]=%d\n", i, pt[i]); }*/ } void find_depth(int v){ if(pt[v]==-1){ depth[v]=0; return; } if(depth[pt[v]]==-1) find_depth(pt[v]); depth[v]=1+depth[pt[v]]; } void lcainit(){ memset(anc, -1, sizeof(anc)); for(int i=0; i<N; ++i) anc[i][0]=pt[i]; for(int l=1; l<17; ++l){ for(int i=0; i<N; ++i){ if(anc[i][l-1]!=-1) anc[i][l]=anc[anc[i][l-1]][l-1]; } } memset(depth, -1, sizeof(depth)); for(int i=0; i<N; ++i){ if(depth[i]==-1)find_depth(i); } } int lca(int u, int v){ if(depth[v]>depth[u])return lca(v, u); for(int l=16; l>=0; --l){ if(depth[u]-depth[v]>=(1<<l)) u=anc[u][l]; } assert(depth[u]==depth[v]); if(u==v)return u; for(int l=16; l>=0; --l){ if(anc[u][l]==anc[v][l]) continue; u=anc[u][l]; v=anc[v][l]; } return pt[u]; } int main(){ ios::sync_with_stdio(false); input(); find_height(); unionfindinit(); maketree(); lcainit(); cin>>Q; for(int i=0; i<Q; ++i){ int s, t; cin>>s>>t; cout<<height[lca(s-1, t-1)]<<endl; } return 0; } /* 9 12 1 9 4 1 2 5 2 3 7 2 4 3 4 3 6 3 6 4 8 7 10 6 7 5 5 8 1 9 5 7 5 4 12 6 8 2 2 4 7 5 1 6 5 3 4 8 5 8 1 5 5 5 1 2 2 5 1 1 4 5 1 3 2 3 3 4 4 1 5 5 5 1 1 2 2 3 4 3 5 4 */
#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...