제출 #1271668

#제출 시각아이디문제언어결과실행 시간메모리
1271668cokalhadoOlympic Bus (JOI20_ho_t4)C++20
0 / 100
321 ms27728 KiB
// https://oj.uz/problem/view/JOI20_ho_t4 #include<bits/stdc++.h> using namespace std; #define int long long const int maxn = 210; const int maxm = 5e4+10; const int inf = 1e18; const int comp = 1e17; int N, M; vector<pair<int, int>> g[maxn][2]; tuple<int, int, int, int> ar[maxm]; int dist[maxn]; bool proc[maxn]; int ans = inf; int P[maxn][4]; void dijkstra(int A, bool b) { for(int i = 1; i <= N; i++) { dist[i] = 0; proc[i] = 0; } priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; pq.push({1, A}); dist[A] = 1; while(!pq.empty()) { int x = pq.top().second; pq.pop(); if(proc[x]) continue; proc[x] = 1; for(auto[v, w] : g[x][b]) { if(dist[v] == 0 || dist[x]+w < dist[v]) { dist[v] = dist[x]+w; pq.push({dist[v], v}); } } } } int32_t main() { srand(time(0)); vector<int> absolute_global_answer; int t = 10; cin >> N >> M; for(int i = 1; i <= M; i++) { int u, v, c, d; cin >> u >> v >> c >> d; ar[i] = make_tuple(u, v, c, d); } while(t--) { ans = inf; for(int i = 1; i <= M; i++) { auto[u, v, c, d] = ar[i]; c = rand()*rand()+rand()+rand()+rand()+1; ar[i] = make_tuple(u, v, c, d); g[u][0].push_back({v, c}); g[v][1].push_back({u, c}); } dijkstra(1, 0); for(int i = 1; i <= N; i++) { P[i][0] = dist[i]-1; // if(P[i][0] == -1) P[i][0] = inf; } dijkstra(N, 1); for(int i = 1; i <= N; i++) { P[i][1] = dist[i]-1; // if(P[i][1] == -1) P[i][1] = inf; } dijkstra(N, 0); for(int i = 1; i <= N; i++) { P[i][2] = dist[i]-1; // if(P[i][2] == -1) P[i][2] = inf; } dijkstra(1, 1); for(int i = 1; i <= N; i++) { P[i][3] = dist[i]-1; // if(P[i][3] == -1) P[i][3] = inf; } if(P[N][0] >= 0 && P[1][2] >= 0) { cout << 0; return 0; } // for(int i = 1; i <= N; i++) // { // cout << "i " << i << " P " << P[i][0] << " " << P[i][1] << " " << P[i][2] << " " << P[i][3] << endl; // } ans = inf; for(int i = 1; i <= M; i++) { auto[u, v, c, d] = ar[i]; // if(i > 2) cout << "i " << i << " " << " u " << u << " v " << v << " "; // for each guy, have P(1, i) P(i, N) P(N, i) P(i, 1) if(P[v][0] >= 0 && P[u][1] >= 0) { if(P[1][2] >= 0) { if(P[1][2] != P[u][2]+c+P[v][3]) { ans = min(ans, d); // cout << "d " << d << " r2" << endl; continue; } else continue; } } if(P[v][2] && P[u][3]) { if(P[N][0] >= 0) { if(P[N][0] != P[u][0]+c+P[u][1]) { ans = min(ans, d); // cout << "d " << d << " r3" << endl; continue; } else continue; } // for each guy, have P(1, i) P(i, N) P(N, i) P(i, 1) } if(P[v][0] >= 0 && P[u][1] >= 0 && P[v][2] >= 0 && P[u][3] >= 0) { ans = min(ans, d); // cout << "d " << d << " r1" << endl; continue; } } absolute_global_answer.push_back(ans); } sort(absolute_global_answer.begin(), absolute_global_answer.end()); int xans = absolute_global_answer[rand()%absolute_global_answer.size()]; if(absolute_global_answer.size() <= 5) { xans = absolute_global_answer.back(); } else { xans = absolute_global_answer[absolute_global_answer.size()-rand()%(2)]; } cout << (xans > comp ? -1 : xans); return 0; // ans = P[N][0]+P[1][2]; // for(int i = 1; i <= M; i++) // { // auto[u, v, c, d] = ar[i]; // ans = min(ans, min(P[N][0], P[v][0]+ min(P[v][1], P[u][1]+c)) + min(P[1][2], P[v][2]+ min(P[v][3], P[u][3]+c)) +d); // } // cout << (ans > comp ? -1 : ans); // return 0; } // sub 2 -> ok after inverting you can still use the other way // for each guy, have P(1, i) P(i, N) P(N, i) P(i, 1). For each V ans = +1, min(+2, P(U, N)+d+c), +3, min(+4, P(U,1)+d+c) // sub 3 -> choose one and just get to the end // maybe do P(1, i) P(i, N) P(N, i) P(i, 1) be the number of ways to get from a place to another // then you can see wether there's another way // make all c have rand(), see if the best path goes through me // for each guy, have P(1, i) P(i, N) P(N, i) P(i, 1)
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...