Submission #1216491

#TimeUsernameProblemLanguageResultExecution timeMemory
1216491InvMODRelay Marathon (NOI20_relaymarathon)C++20
100 / 100
1417 ms80848 KiB
#include<bits/stdc++.h> using namespace std; #define pb push_back #define all(v) (v).begin(), (v).end() template<typename T> bool ckmn(T& a, const T& b){ if(a > b) return a = b, true; return false; } const int N = 1e5 + 5, M = 3e6 + 5, INF = 1e9; /* minimum distance = (a,b) {x1, y1} != (a) and (b) -> optimal to choose (a,b) {(a), y1} != (b) -> if we choose {x2, y2} != (a) and (b) we should choose (a,b) -> we have to choose {(b), y2} */ struct Edge{ int u,v,w; Edge(int u = 0, int v = 0, int w = 0): u(u), v(v), w(w) {} }; int n, m, k, dist[N], near[N]; bool special[N]; Edge E[M]; vector<int> adj[N]; void dijkstra(){ priority_queue<pair<int,int>> pq; for(int i = 1; i <= n; i++){ if(special[i]) pq.push(make_pair(0, i)); } while(!pq.empty()){ pair<int,int> e = pq.top(); pq.pop(); int x = e.second, cur_dist = -e.first; if(cur_dist > dist[x]) continue; for(int id : adj[x]){ int v = E[id].u ^ E[id].v ^ x, w = E[id].w; if(ckmn(dist[v], dist[x] + w)){ near[v] = near[x]; pq.push(make_pair(-dist[v], v)); } } } } void solve() { cin >> n >> m >> k; for(int i = 0; i < m; i++){ int u,v,w; cin >> u >> v >> w; E[i] = Edge(u, v, w); adj[u].pb(i), adj[v].pb(i); } for(int i = 0; i < k; i++){ int x; cin >> x; special[x] = true; } auto reset = [&]() -> void{ for(int i = 1; i <= n; i++){ if(special[i]) dist[i] = 0, near[i] = i; else dist[i] = INF, near[i] = 0; } }; reset(), dijkstra(); int opt1 = -1, opt2 = -1, cdist = INF; for(int i = 0; i < m; i++){ int u = E[i].u, v = E[i].v, w = E[i].w; if(near[u] == near[v]) continue; if(ckmn(cdist, dist[u] + dist[v] + w)){ opt1 = near[u]; opt2 = near[v]; } } special[opt1] = special[opt2] = false; // cout << "FOUND OPT: " << opt1 <<" " << opt2 << "\n"; reset(), dijkstra(); int answer = INF; for(int i = 0; i < m; i++){ int u = E[i].u, v = E[i].v, w = E[i].w; if(near[u] == near[v]) continue; ckmn(answer, cdist + dist[u] + dist[v] + w); } vector<int> MnOpt1(n + 1, INF); special[opt1] = true; reset(), dijkstra(); for(int i = 0; i < m; i++){ int u = E[i].u, v = E[i].v, w = E[i].w; if(near[u] == near[v]) continue; if(near[u] == opt1 || near[v] == opt1){ int target = (near[u] == opt1 ? near[v] : near[u]); ckmn(MnOpt1[target], dist[u] + dist[v] + w); } } special[opt1] = false; vector<int> MnOpt2(n + 1, INF); special[opt2] = true; reset(), dijkstra(); for(int i = 0; i < m; i++){ int u = E[i].u, v = E[i].v, w = E[i].w; if(near[u] == near[v]) continue; if(near[u] == opt2 || near[v] == opt2){ int target = (near[u] == opt2 ? near[v] : near[u]); ckmn(MnOpt2[target], dist[u] + dist[v] + w); } } vector<int> idx1(n + 1, 0), idx2(n + 1, 0); for(int i = 1; i <= n; i++) idx1[i] = idx2[i] = i; sort(1 + all(idx1), [&](int x, int y){return MnOpt1[x] < MnOpt1[y];}); sort(1 + all(idx2), [&](int x, int y){return MnOpt2[x] < MnOpt2[y];}); int last_dist1 = MnOpt1[idx1[1]] + MnOpt2[(idx1[1] == idx2[1] ? idx2[2] : idx2[1])]; int last_dist2 = MnOpt2[idx2[1]] + MnOpt1[(idx2[1] == idx1[1] ? idx1[2] : idx1[1])]; answer = min(answer, min(last_dist1, last_dist2)); cout << answer << "\n"; } int32_t main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define name "InvMOD" if(fopen(name".INP", "r")){ freopen(name".INP", "r", stdin); freopen(name".OUT", "w", stdout); } solve(); return 0; }

Compilation message (stderr)

RelayMarathon.cpp: In function 'int32_t main()':
RelayMarathon.cpp:148:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  148 |         freopen(name".INP", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
RelayMarathon.cpp:149:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  149 |         freopen(name".OUT", "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...