Submission #979090

#TimeUsernameProblemLanguageResultExecution timeMemory
979090Br3adToll (APIO13_toll)C++17
0 / 100
0 ms344 KiB
#include <iostream> #include <fstream> #include <iomanip> #include <algorithm> #include <functional> #include <numeric> #include <cstring> #include <string> #include <cmath> #include <vector> #include <queue> #include <stack> #include <set> #include <map> using namespace std; #define ll long long #define ull unsigned long long #define f first #define s second #define PF push_front #define PB push_back #define MP make_pair #define max(a, b) ((a > b)? a : b) #define min(a, b) ((a < b)? a : b) #define max3(a, b, c) max(max(a, b), c) #define min3(a, b, c) min(min(a, b), c) const int N = 1e5 + 5; const int M = 1e9 + 7; const int inf = 0x3f3f3f3f; const ll int INF = 1e18; struct DSU { vector<int> parent; DSU(int n){ parent = vector<int>(n+1); iota(parent.begin(), parent.end(), 0); } int find_parent(int p){ return (parent[p] == p)? p : parent[p] = find_parent(parent[p]); } bool merge(int a, int b){ a = find_parent(a); b = find_parent(b); parent[a] = b; return (a != b); } }; struct TREE { map<pair<int, int>, bool> isPath; vector<vector<pair<int, int>>> tree_adj; vector<int> parent, sz; ll total = 0, limit = 0; TREE(int n, vector<int> &people){ tree_adj = vector<vector<pair<int, int>>>(n+1); parent = vector<int>(n+1); iota(parent.begin(), parent.end(), 0); sz = people; } void dfs(int cur, int prev, vector<vector<pair<int, int>>> &adj){ for(auto [child, cost] : tree_adj[cur]){ if(child == prev) continue; dfs(child, cur, adj); if(cost == 0){ // edge (cur, child) is one of the new roads int new_cost = find_min(child, adj); total += 1ll * new_cost * sz[child]; } sz[cur] += sz[child]; } } int find_min(int cur, vector<vector<pair<int, int>>> &adj){ int mn = inf; for(auto [neighbour, weight] : adj[cur]){ pair<int, int> cur_edge = MP(min(cur, neighbour), max(cur, neighbour)); if(isPath[cur_edge]) continue; mn = min(mn, weight); } return mn; } }; int main(){ ios::sync_with_stdio(false); cin.tie(NULL); // ifstream cin(); // ofstream cout(); int n, m, k; cin >> n >> m >> k; vector<vector<pair<int, int>>> adj(n+1, vector<pair<int, int>>()); vector<pair<int, pair<int, int>>> edge; for(int i = 0; i < m; i++){ int a, b, w; cin >> a >> b >> w; adj[a].PB(MP(b, w)); adj[b].PB(MP(a, w)); edge.PB(MP(w, MP(a, b))); } for(int i = 0; i < k; i++){ int a, b; cin >> a >> b; adj[a].PB(MP(b, 0)); adj[b].PB(MP(a, 0)); edge.PB(MP(0, MP(a, b))); } vector<int> people(n+1); for(int i = 1; i <= n; i++) cin >> people[i]; // Create minimum spanning tree which new roads are included sort(edge.begin(), edge.end()); DSU dsu(n); TREE tree(n, people); for(auto [w, p] : edge){ if(dsu.merge(p.f, p.s)){ tree.tree_adj[p.f].PB(MP(p.s, w)); tree.tree_adj[p.s].PB(MP(p.f, w)); pair<int, int> cur_edge = MP(min(p.f, p.s), max(p.f, p.s)); tree.isPath[cur_edge] = true; tree.limit = max(tree.limit, w); } } // Traverse tree to calculate road passers and maximum toll fees for new roads tree.dfs(1, -1, adj); cout << tree.total << endl; } /* 5 5 1 3 5 2 1 2 3 2 3 5 2 4 4 4 3 6 1 3 10 20 30 40 50 */
#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...