CSES - Aalto Competitive Programming 2024 - wk7 Homework - Results
Submission details
Task:Download Speed
Sender:snude
Submission time:2024-10-19 11:05:42 +0300
Language:C++ (C++11)
Status:READY
Result:ACCEPTED
Test results
testverdicttime
#1ACCEPTED0.00 sdetails
#2ACCEPTED0.00 sdetails
#3ACCEPTED0.00 sdetails
#4ACCEPTED0.00 sdetails
#5ACCEPTED0.03 sdetails
#6ACCEPTED0.01 sdetails
#7ACCEPTED0.01 sdetails
#8ACCEPTED0.00 sdetails
#9ACCEPTED0.00 sdetails
#10ACCEPTED0.00 sdetails
#11ACCEPTED0.01 sdetails
#12ACCEPTED0.00 sdetails

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