Task: | Download Speed |
Sender: | snude |
Submission time: | 2024-10-19 11:05:42 +0300 |
Language: | C++ (C++11) |
Status: | READY |
Result: | ACCEPTED |
test | verdict | time | |
---|---|---|---|
#1 | ACCEPTED | 0.00 s | details |
#2 | ACCEPTED | 0.00 s | details |
#3 | ACCEPTED | 0.00 s | details |
#4 | ACCEPTED | 0.00 s | details |
#5 | ACCEPTED | 0.03 s | details |
#6 | ACCEPTED | 0.01 s | details |
#7 | ACCEPTED | 0.01 s | details |
#8 | ACCEPTED | 0.00 s | details |
#9 | ACCEPTED | 0.00 s | details |
#10 | ACCEPTED | 0.00 s | details |
#11 | ACCEPTED | 0.01 s | details |
#12 | ACCEPTED | 0.00 s | details |
Code
#include <algorithm> #include <climits> #include <cmath> #include <iostream> #include <queue> #include <vector> // Debug printing #ifdef DEBUG #define deb(fmt, args...) printf("DEBUG: %d: " fmt, __LINE__, ##args) #else #define deb(fmt, args...) #endif using namespace std; using ll = long long; void print_array(vector<int> in, const string title = "Vector") { cout << title << " [\n"; for (const auto &el : in) { cout << el << " "; } cout << "\n] END\n"; } void print_matrix(vector<vector<int> > in, const string title = "Matrix") { cout << title << " [\n"; for (unsigned int i = 0; i < in.size(); i++) { cout << "row " << i << ": "; for (unsigned int j = 0; j < in[i].size(); j++) { cout << in[i][j] << " "; } cout << "\n"; } cout << "] END\n"; } int target; int found = true; vector<int> path; bool visited[500]; void dfs(int vert, vector<vector<int> > &adj, vector<vector<int> > &edges) { if (found) { return; } if (visited[vert]) { return; }; visited[vert] = true; if (vert == target) { found = true; return; } for (auto u : adj[vert]) { int b = edges[u][1]; int c = edges[u][2]; // deb("s: %d, a: %d, b: %d, c: %d\n", s, a, b, c); if (c > 0) { path.push_back(u); // Add edge to path dfs(b, adj, edges); if (found) return; path.pop_back(); // remove edge from path } } } void dijkstra(vector<vector<int> > &adj, vector<vector<int> > &edges, int n, vector<int> &path) { priority_queue<pair<ll, ll> > q; vector<int> distance(n + 1, INT_MAX); vector<int> predecessor(n + 1, 0); vector<bool> processed(n + 1, false); distance[1] = 0; q.push({ 0, 1 }); while (!q.empty()) { ll a = q.top().second; q.pop(); if (processed[a]) continue; processed[a] = true; for (auto u : adj[a]) { vector<int> edge = edges[u]; if (edge[2] < 1) continue; ll b = edge[1], w = 1; if (distance[a] + w < distance[b]) { distance[b] = distance[a] + w; predecessor[b] = u; q.push({ -distance[b], b }); } } } // print_array(distance, "dist"); // deb("dijkstra tehty\n"); // print_array(predecessor, "pred"); // find shortest path if (predecessor[n] == 0) { found = false; return; } found = true; int v = n; int e = predecessor[v]; int index = 0; while (v != 1) { e = predecessor[v]; path.push_back(e); v = edges[e][0]; deb("v: %d, e: %d\n", v, e); index++; } reverse(path.begin(), path.end()); } int main(int argc, char *argv[]) { int n, m; cin >> n >> m; target = n; // each edge is of form (a, b, c) vector<vector<int> > edges(m + 1, vector<int>(3)); for (int i = 1; i < m + 1; i++) { cin >> edges[i][0] >> edges[i][1] >> edges[i][2]; } // adjacent structure contains the edge indices that are adjacent to the // node vector<vector<int> > adj(n + 1, vector<int>()); for (int j = 1; j < m + 1; j++) { adj[edges[j][0]].push_back(j); } // print_matrix(edges, "edges"); // print_matrix(adj, "adjacent"); ll speed = 0; while (found) { found = false; for (int i = 0; i < n + 1; i++) visited[i] = false; path.clear(); // dfs(1, adj, edges); dijkstra(adj, edges, n, path); // print_array(path, "path"); if (found) { int residual = INT_MAX; // find residual capacity of the path for (auto e : path) { vector<int> edge = edges[e]; if (edge[2] < residual) residual = edge[2]; } deb("res: %d\n", residual); speed += residual; // update flows for (auto e : path) { edges[e][2] -= residual; } } } cout << speed << "\n"; return 0; }
Test details
Test 1
Verdict: ACCEPTED
input |
---|
4 3 1 2 5 2 3 3 3 4 6 |
correct output |
---|
3 |
user output |
---|
3 |
Test 2
Verdict: ACCEPTED
input |
---|
4 5 1 2 1 1 3 1 2 3 1 2 4 1 ... |
correct output |
---|
2 |
user output |
---|
2 |
Test 3
Verdict: ACCEPTED
input |
---|
4 5 1 2 1000000000 1 3 1000000000 2 3 1 2 4 1000000000 ... |
correct output |
---|
2000000000 |
user output |
---|
2000000000 |
Test 4
Verdict: ACCEPTED
input |
---|
2 1 2 1 100 |
correct output |
---|
0 |
user output |
---|
0 |
Test 5
Verdict: ACCEPTED
input |
---|
2 1000 1 2 1000000000 1 2 1000000000 1 2 1000000000 1 2 1000000000 ... |
correct output |
---|
1000000000000 |
user output |
---|
1000000000000 |
Test 6
Verdict: ACCEPTED
input |
---|
500 998 1 2 54 1 3 59 1 4 83 2 5 79 ... |
correct output |
---|
60 |
user output |
---|
60 |
Test 7
Verdict: ACCEPTED
input |
---|
500 998 1 2 530873053 1 3 156306296 1 4 478040476 3 5 303609600 ... |
correct output |
---|
1093765123 |
user output |
---|
1093765123 |
Test 8
Verdict: ACCEPTED
input |
---|
2 1 1 2 1 |
correct output |
---|
1 |
user output |
---|
1 |
Test 9
Verdict: ACCEPTED
input |
---|
4 5 1 2 3 2 4 2 1 3 4 3 4 5 ... |
correct output |
---|
6 |
user output |
---|
6 |
Test 10
Verdict: ACCEPTED
input |
---|
4 5 1 2 1 1 3 2 3 2 1 2 4 2 ... |
correct output |
---|
3 |
user output |
---|
3 |
Test 11
Verdict: ACCEPTED
input |
---|
10 999 1 2 1000000000 1 2 1000000000 1 2 1000000000 1 2 1000000000 ... |
correct output |
---|
111000000000 |
user output |
---|
111000000000 |
Test 12
Verdict: ACCEPTED
input |
---|
7 9 1 2 1 1 3 1 1 4 1 2 5 1 ... |
correct output |
---|
2 |
user output |
---|
2 |