제출 #233741

#제출 시각아이디문제언어결과실행 시간메모리
233741nicolaalexandraCommuter Pass (JOI18_commuter_pass)C++14
100 / 100
778 ms44000 KiB
#include <bits/stdc++.h> #define DIM 100010 #define INF 2000000000000000000LL using namespace std; priority_queue <pair<long long,int>, vector<pair<long long,int> >, greater<pair<long long,int> > > H; priority_queue <pair<long long,pair<int,int> >, vector<pair<long long,pair<int,int> > >, greater <pair<long long,pair<int,int> > > > c; vector <pair<int,long long> > L[DIM]; vector <int> fth[DIM],edg[DIM]; long long dist_s[DIM],dist_u[DIM],dist_t[DIM],dp[DIM][5]; int viz[DIM]; int n,m,s,t,x,y,i,u,v; long long cost; void dfs (int nod){ viz[nod] = 1; for (auto vecin : fth[nod]) if (!viz[vecin]){ edg[vecin].push_back(nod); dfs (vecin); } } void dijkstra (long long dp[], int start){ for (i=1;i<=n;i++) dp[i] = INF; dp[start] = 0; while (!H.empty()) H.pop(); //H.clear(); H.push (make_pair(0,start)); while (!H.empty()){ int nod = H.top().second; long long cost = H.top().first; H.pop(); if (dp[nod] < cost) continue; for (auto it : L[nod]){ int vecin = it.first; long long new_cost = it.second; if (dp[nod] + new_cost < dp[vecin]){ dp[vecin] = dp[nod] + new_cost; H.push(make_pair(dp[vecin],vecin)); }}}} int main (){ // ifstream cin ("date.in"); // ofstream cout ("date.out"); cin>>n>>m>>s>>t>>u>>v; for (i=1;i<=m;i++){ cin>>x>>y>>cost; L[x].push_back(make_pair(y,cost)); L[y].push_back(make_pair(x,cost)); } for (i=1;i<=n;i++) dist_s[i] = INF; dist_s[s] = 0; H.push(make_pair(0,s)); while (!H.empty()){ int nod = H.top().second; long long cost = H.top().first; H.pop(); if (dist_s[nod] < cost) continue; for (auto it : L[nod]){ int vecin = it.first; long long new_cost = it.second; if (dist_s[nod] + new_cost < dist_s[vecin]){ dist_s[vecin] = dist_s[nod] + new_cost; fth[vecin].clear(); fth[vecin].push_back(nod); H.push(make_pair(dist_s[vecin],vecin)); } else { if (dist_s[nod] + new_cost == dist_s[vecin]) fth[vecin].push_back(nod); }}} /// marchez toate nodurile care se afla pe drumurile minime de la S la T viz[t] = 1; dfs (t); //dijkstra (dist_u,u); //dijkstra (dist_v,v); dijkstra (dist_t,t); /// dp[nod][stare] - distanta minima de la u la un nod /// 0 - nu am intrat pe un drum minim /// 1 - merg pe un drum minim spre t /// 2 - merg pe un drum minim spre s /// 3 - am mers pe un drum minim, dar acum nu mai sunt for (i=1;i<=n;i++) dp[i][0] = dp[i][1] = dp[i][2] = dp[i][3] = INF; dp[u][0] = 0; c.push(make_pair(0,make_pair(u,0))); if (viz[u]){ dp[u][1] = dp[u][2] = 0; c.push(make_pair(0,make_pair(u,1))); c.push(make_pair(0,make_pair(u,2))); } while (!c.empty()){ int nod = c.top().second.first; int stare = c.top().second.second; long long cost = c.top().first; c.pop(); if (dp[nod][stare] < cost) continue; for (auto it : L[nod]){ int vecin = it.first; long long new_cost = it.second; if (stare == 0){ if (dp[nod][stare] + new_cost < dp[vecin][stare]){ dp[vecin][stare] = dp[nod][stare] + new_cost; c.push(make_pair(dp[vecin][stare],make_pair(vecin,stare))); } if (viz[vecin]){ /// pot sa actualizez dp[vecin][1/2] if (dp[nod][stare] + new_cost < dp[vecin][1]){ dp[vecin][1] = dp[nod][stare] + new_cost; c.push(make_pair(dp[vecin][1],make_pair(vecin,1))); } if (dp[nod][stare] + new_cost < dp[vecin][2]){ dp[vecin][2] = dp[nod][stare] + new_cost; c.push(make_pair(dp[vecin][2],make_pair(vecin,2))); }} } else { if (stare == 1){ if (dist_s[vecin] + new_cost + dist_t[nod] == dist_s[t]){ /// pot sa pastrez starea asta if (dp[nod][stare] < dp[vecin][stare]){ dp[vecin][stare] = dp[nod][stare]; c.push(make_pair(dp[vecin][stare],make_pair(vecin,stare))); } } /// trec in starea 3 if (dp[nod][stare] + new_cost < dp[vecin][3]){ dp[vecin][3] = dp[nod][stare] + new_cost; c.push(make_pair(dp[vecin][3],make_pair(vecin,3))); } } else { if (stare == 2){ if (dist_s[nod] + new_cost + dist_t[vecin] == dist_s[t]){ /// pot sa pastrez starea asta if (dp[nod][stare] < dp[vecin][stare]){ dp[vecin][stare] = dp[nod][stare]; c.push(make_pair(dp[vecin][stare],make_pair(vecin,stare))); } } /// trec in starea 3 if (dp[nod][stare] + new_cost < dp[vecin][3]){ dp[vecin][3] = dp[nod][stare] + new_cost; c.push(make_pair(dp[vecin][3],make_pair(vecin,3))); } } else { /// stare == 3 /// acum pot doar sa trec in starea 3 if (dp[nod][stare] + new_cost < dp[vecin][stare]){ dp[vecin][stare] = dp[nod][stare] + new_cost; c.push(make_pair(dp[vecin][stare],make_pair(vecin,stare))); }}}}}} cout<<min(min(dp[v][0],dp[v][1]),min(dp[v][2],dp[v][3])); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...