Submission #1125708

#TimeUsernameProblemLanguageResultExecution timeMemory
1125708CodeLakVNVoting Cities (NOI22_votingcity)C++20
15 / 100
1095 ms1256 KiB
#include <bits/stdc++.h> using namespace std; #define Task "VOTINGCITY" #define ll long long #define FOR(i, a, b) for (int i = (a); i <= (b); i++) #define FOD(i, a, b) for (int i = (a); i >= (b); i--) #define F first #define S second typedef pair<int, int> ii; typedef pair<ll, int> li; const int N = 5e3 + 5; const ll INF = 1e18; const int MOD = 1e9 + 7; template<class X, class Y> bool minimize(X &x, Y y) { if (x > y) { x = y; return true; } else return false; } int numNode, numEdge, numQuery, numSpec; int specNode[N]; vector<ii> adj[N]; struct QUERY { int s; int price[6]; } query[105]; ll dist[N]; void dijkstra(int s) { priority_queue<li, vector<li>, greater<li>> pq; pq.push({0, s}); memset(dist, 0x3f, sizeof(dist)); dist[s] = 0; while (!pq.empty()) { li p = pq.top(); pq.pop(); int u = p.S; ll d = p.F; if (d > dist[u]) continue; for (ii e : adj[u]) { int v = e.F, w = e.S; if (minimize(dist[v], dist[u] + w)) pq.push({dist[v], v}); } } } namespace sub3 { bool valid() { FOR(i, 1, numQuery) if (*max_element(query[i].price + 1, query[i].price + 6) > -1) return false; return true; } void solve() { FOR(i, 1, numQuery) { int s = query[i].s; dijkstra(s); ll ans = dist[0]; FOR(j, 1, numSpec) minimize(ans, dist[specNode[j]]); cout << (ans == dist[0] ? -1 : ans) << "\n"; } } } namespace sub7 { // + iterate over possible groups of tickets that are bought // + run dijkstra from s with 3 states {dist, u, bitmask (the ith bit is on if the ticket i was bought)} // + iterate over special nodes to minimize the answer bool isValidMask(int mask, int queryID) { FOR(i, 0, 4) if (mask >> i & 1) { if (query[queryID].price[i + 1] == -1) return false; } return true; } struct STATE { int u; long long dist; int mask; bool operator < (const STATE &other) const { return dist > other.dist; } }; ll dist[105][33]; void dijkstra(int s, int tickets) { priority_queue<STATE> pq; pq.push({s, 0, 0}); memset(dist, 0x3f, sizeof(dist)); dist[s][0] = 0; while (!pq.empty()) { STATE t = pq.top(); pq.pop(); int u = t.u, preMask = t.mask; long long d = t.dist; if (d < dist[u][preMask]) continue; for (ii e : adj[u]) { int v = e.F, w = e.S; if (minimize(dist[v][preMask], dist[u][preMask] + 1LL * w)) pq.push({v, dist[v][preMask], preMask}); FOR(i, 0, 4) if (!(preMask >> i & 1) && (tickets >> i & 1)) { int newMask = preMask | (1 << i); if (minimize(dist[v][newMask], dist[u][preMask] + 1LL * w - 1LL * w * (i + 1) / 10)) pq.push({v, dist[v][newMask], newMask}); } } } } long long solveForQuery(int tickets, int queryID) { dijkstra(query[queryID].s, tickets); ll res = dist[0][0]; FOR(i, 1, numSpec) minimize(res, dist[specNode[i]][tickets]); return res; } void solve() { FOR(t, 1, numQuery) { ll ans = INF; FOR(mask, 0, (1 << 5) - 1) { if (!isValidMask(mask, t)) continue; ll cur = solveForQuery(mask, t); ll ticketsCost = 0; FOR(i, 0, 4) if (mask >> i & 1) ticketsCost += 1LL * query[t].price[i + 1]; minimize(ans, cur + ticketsCost); } cout << (ans == INF ? -1 : ans) << "\n"; } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); if (fopen(Task".INP", "r")) { freopen(Task".INP", "r", stdin); freopen(Task".OUT", "w", stdout); } cin >> numNode >> numEdge >> numSpec; FOR(i, 1, numSpec) cin >> specNode[i], specNode[i]++; FOR(i, 1, numEdge) { int u, v, w; cin >> u >> v >> w; u++; v++; adj[u].push_back({v, w}); } cin >> numQuery; FOR(i, 1, numQuery) { cin >> query[i].s; query[i].s++; FOR(j, 1, 5) cin >> query[i].price[j]; } if (sub3::valid()) sub3::solve(); else sub7::solve(); return 0; }

Compilation message (stderr)

Main.cpp: In function 'int main()':
Main.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(Task".INP", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:150:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  150 |         freopen(Task".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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...