제출 #826331

#제출 시각아이디문제언어결과실행 시간메모리
826331MohamedAliSaidaneOlympic Bus (JOI20_ho_t4)C++14
0 / 100
2 ms340 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define pb push_back #define all(x) (x).begin(), (x).end() #define ff first #define ss second const int nax = 205; const int fax = 5e4 + 4; const int INF = 1e9; int n, m; int seen[nax]; int sp1[nax], ps1[nax], sp2[nax], ps2[nax]; vector<int> adj[nax], rev_adj[nax]; int U[fax], V[fax], is_on_path[fax]; int C[fax]; ll D[fax]; int previ[nax][4]; int vis[nax][nax]; void calculate_sp(int up = -1, int vp = -1, int edg = -1) { priority_queue <pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq; for(int i = 1; i <= n; i++) { sp1[i] = ps1[i] = sp2[i] = ps2[i] = INF; seen[i] = 0; } sp1[1] = ps1[1] = sp2[n] = ps2[n] = 0ll; previ[1][0] = previ[1][1] = -1; pq.push({0, 1}); while(!pq.empty()) { pair<int,int> E = (pq.top()); pq.pop(); int node = E.ss; if(seen[node]) continue; seen[node] = 1; int path = E.ff; if(previ[node][0] != -1) is_on_path[previ[node][0]] = 1; for(auto e: adj[node]) { if(e == edg) continue; int v = V[e]; if(sp1[v] <= path + C[e]) continue; sp1[v] = path + C[e]; previ[v][0] = e; pq.push({path + C[e], v}); } if(node == vp) { int v = up; if(sp1[v] <= path + C[edg]) continue; sp1[v] = path + C[edg]; pq.push({path + C[edg], v}); } } for(int i= 1; i <= n; i++) seen[i] = 0; pq.push({0, 1}); while(!pq.empty()) { pair<int,int> E = (pq.top()); pq.pop(); int node = E.ss; if(seen[node]) continue; seen[node] = 1; int path = E.ff; if(previ[node][1] != -1) is_on_path[previ[node][1]] = 1; for(auto e: rev_adj[node]) { if(e == edg) continue; int v = U[e]; if(ps1[v] <= path + C[e]) continue; ps1[v] = path + C[e]; pq.push({path + C[e], v}); } if(node == up) { int v = vp; if(ps1[v] <= path + C[edg]) continue; ps1[v] = path + C[edg]; pq.push({path + C[edg], v}); } } previ[n][2] = previ[n][3] = -1; for(int i =1; i <= n; i++) seen[i] = 0; pq.push({0, n}); while(!pq.empty()) { pair<int,int> E = (pq.top()); pq.pop(); int node = E.ss; if(seen[node]) continue; seen[node] = 1; int path = E.ff; if(previ[node][2] != -1) is_on_path[previ[node][2]] = 1; for(auto e: adj[node]) { if(e == edg) continue; int v = V[e]; if(sp2[v] <= path + C[e]) continue; sp2[v] = path + C[e]; previ[v][2] = e; pq.push({path + C[e], v}); } if(node == vp) { int v = up; if(sp2[v] <= path + C[edg]) continue; sp2[v] = path + C[edg]; pq.push({path + C[edg], v}); } } for(int i =1; i <= n; i++) seen[i] = 0; pq.push({0, n}); while(!pq.empty()) { pair<int,int> E = (pq.top()); pq.pop(); int node = E.ss; if(seen[node]) continue; seen[node] = 1; int path = E.ff; if(previ[node][3] != -1) is_on_path[previ[node][3]] = 1; for(auto e: rev_adj[node]) { if(e == edg) continue; int v = U[e]; if(ps2[v] <= path + C[e]) continue; ps2[v] = path + C[e]; previ[v][3] = e; pq.push({path + C[e], v}); } if(node == up) { int v = vp; if(ps2[v] <= path + C[edg]) continue; ps2[v] = path + C[edg]; pq.push({path + C[edg], v}); } } assert(sp1[1] == 0); assert(sp2[n] == 0); assert(sp1[n] == ps2[1]); assert(sp2[1] == ps1[n]); } void solve() { cin >> n >> m; vector<pair<int,int>> VEC; for(int i = 0; i < m; i++) { cin >> U[i] >> V[i] >> C[i] >> D[i]; VEC.pb({C[i], i}); } sort(all(VEC)); for(auto p: VEC) { int e = p.ss; if(vis[U[e]][V[e]] == 2) continue; adj[U[e]].pb(e); rev_adj[V[e]].pb(e); vis[U[e]][V[e]]++; } calculate_sp(); vector<int> NON, YES; for(int i = 0; i < m; i++) { if(is_on_path[i]) YES.pb(i); else NON.pb(i); } assert((int)(YES.size()) <= 4 * n); ll ans = sp1[n] >= INF || sp2[1] >= INF? 2ll * INF: sp1[n] + sp2[1]; for(auto i: NON) { int u = U[i], v = V[i]; ll c = C[i], d = D[i]; ll un = sp1[n]; ll uV = sp1[v]; ll Un = ps2[u]; ll nu = sp2[1]; ll nV = sp2[v]; ll Uu = ps1[u]; if((un >= INF && uV + c + Un >= INF) || (nu >= INF && nV + c + Uu >= INF)) continue; ll rep = d + min(un, uV + c + Un) + min(nu, nV + c + Uu); ans = min(ans, rep); } for(auto i: YES) { calculate_sp(U[i], V[i], i); if(sp1[n] >= INF || sp2[1] >= INF) continue; ans = min(ans, (ll)(sp1[n]) + (ll)(sp2[1]) + D[i]); //cout << sp1[n] << ' ' << sp2[1] << '\n'; } if(ans >= 2ll * INF) cout << "-1"; else cout << ans; } int32_t main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); #ifndef ONLINE_JUDGE freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); #endif int tt = 1; // cin >> tt; while(tt--) solve(); }

컴파일 시 표준 에러 (stderr) 메시지

ho_t4.cpp: In function 'int32_t main()':
ho_t4.cpp:248:9: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  248 |  freopen("input.txt", "r", stdin);
      |  ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
ho_t4.cpp:249:9: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  249 |  freopen("output.txt", "w", stdout);
      |  ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...