제출 #510205

#제출 시각아이디문제언어결과실행 시간메모리
510205CSQ31Olympic Bus (JOI20_ho_t4)C++17
0 / 100
316 ms262148 KiB
#include <bits/stdc++.h> using namespace std; typedef long long int ll; const int MAXN = 5e4+5; const ll INF = 1e18; #define sz(a) (int)(a.size()) ll c[MAXN],d[MAXN],dist[MAXN]; int n,m; array<int,2>par[201]; vector<array<int,2>>g[201],gr[201]; bool block[MAXN],vis[201]; void djikstra(int v,vector<array<int,2>>*g){ for(int i=1;i<=n;i++)dist[i] = INF,vis[i] = 0; dist[v] = 0; while(true){ int u = 0; for(int i=1;i<=n;i++)if(dist[i] < dist[u] && !vis[i])u = i; if(!u)break; vis[u] = 1; for(auto x:g[u]){ if(block[x[1]])continue; if(dist[u] + c[x[1]] < dist[x[0]]){ dist[x[0]] = dist[u] + c[x[1]]; par[x[0]] = {u,x[1]}; } } } } ll force[2][201],notused[2][201]; ll secbest[201]; vector<int>path; vector<ll>cut; int main() { cin>>n>>m; ll thonk = 0; dist[0] = INF; vector<array<int,2>>edge; for(int i=0;i<m;i++){ int v,u; cin>>v>>u>>c[i]>>d[i]; g[v].push_back({u,i}); gr[u].push_back({v,i}); edge.push_back({v,u}); } //second best paths for 1->v secbest[1] = INF; for(int i=2;i<=n;i++){ block[par[i][1]] = 1; djikstra(1,g); secbest[i] = dist[i]; block[par[i][1]] = 0; } //whats contribution if inverted ith edge is forced/forbidden on 1->n? djikstra(1,g); thonk+=dist[n]; //v->u to u->v go to u first for(int i=0;i<m;i++){ force[0][i] = dist[edge[i][1]]; notused[0][i] = dist[n]; } if(dist[n] != INF){ int cur = n; while(cur!=1){ path.push_back(par[cur][1]); cur = par[cur][0]; } reverse(path.begin(),path.end()); cut.resize(sz(path)); for(int i=0;i<sz(path);i++){ int x = path[i]; block[x] = 1; djikstra(1,g); cut[i] = dist[n]; block[x] = 0; } } for(int i=0;i<sz(path);i++)notused[0][path[i]] = cut[i]; //take from cut if intersect for(int i=0;i<m;i++){ int v = edge[i][1]; if(i == par[v][1])force[0][i] = secbest[v]; //if intersect take second best edge instead } djikstra(n,gr); for(int i=0;i<m;i++)force[0][i]+=dist[edge[i][0]] + c[i]; /* for(int i=0;i<m;i++)cout<<notused[0][i]<<" "; cout<<'\n'; for(int i=0;i<m;i++)cout<<force[0][i]<<" "; cout<<'\n'; * */ ////// secbest[1] = INF; for(int i=2;i<=n;i++){ block[par[i][1]] = 1; djikstra(n,g); secbest[i] = dist[i]; block[par[i][1]] = 0; } //whats contribution if inverted ith edge is forced/forbidden on 1->n? djikstra(n,g); thonk+=dist[1]; //v->u to u->v go to u first for(int i=0;i<m;i++){ force[1][i] = dist[edge[i][1]]; notused[1][i] = dist[1]; } if(dist[1] != INF){ int cur = 1; while(cur!=n){ path.push_back(par[cur][1]); cur = par[cur][0]; } reverse(path.begin(),path.end()); cut.resize(sz(path)); for(int i=0;i<sz(path);i++){ int x = path[i]; block[x] = 1; djikstra(n,g); cut[i] = dist[1]; block[x] = 0; } } for(int i=0;i<sz(path);i++)notused[1][path[i]] = cut[i]; //take from cut if intersect for(int i=0;i<m;i++){ int v = edge[i][1]; if(i == par[v][1])force[1][i] = secbest[v]; //if intersect take second best edge instead } djikstra(1,gr); for(int i=0;i<m;i++)force[1][i]+=dist[edge[i][0]] + c[i]; /* for(int i=0;i<m;i++)cout<<notused[1][i]<<" "; cout<<'\n'; for(int i=0;i<m;i++)cout<<force[1][i]<<" "; cout<<'\n'; */ ll ans = min(INF,thonk); for(int i=0;i<m;i++)ans = min(ans,min(notused[0][i],force[0][i]) + min(notused[1][i],force[1][i]) + d[i]); if(ans == INF)ans = -1; cout<<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...