10986 – Sending email


Given a network of servers and the connections between them with their latency, find the fastest path for sending a message.

A straight-forward path finding problem. Dijkstra will do and Bellman Ford will get TLE.

#include <algorithm>
#include <iostream>
#include <limits>
#include <vector>
#include <queue>
#include <map>
using namespace std;

vector<map<int, int> > graph;

vector<int> dijkstraD, dijkstraP;
void dijkstra(int s) {
	dijkstraD = vector<int>(graph.size(), numeric_limits<int>::max());
	dijkstraP = vector<int>(graph.size(), -1);
	priority_queue<pair<int, int> > q;
	dijkstraP[s] = -s - 1;
	dijkstraD[s] = 0;
	q.push(make_pair(dijkstraD[s], s));
	while (!q.empty()) {
		pair<int, int> p = q.top();
		q.pop();
		if (dijkstraP[p.second] < 0) {
			dijkstraP[p.second] = -dijkstraP[p.second] - 1;
			for (map<int, int>::iterator itr = graph[p.second].begin();
				itr != graph[p.second].end(); ++itr)
				if (dijkstraP[itr->first] < 0
				&& dijkstraD[p.second] + graph[p.second][itr->first] < dijkstraD[itr->first]) {
					dijkstraP[itr->first] = -p.second - 1;
					dijkstraD[itr->first] = dijkstraD[p.second] + graph[p.second][itr->first];
					q.push(pair<int, int>(-dijkstraD[itr->first], itr->first));
				}
		}
	}
}

int main() {
	int N, n, m, s, t;
	cin >> N;
	for (int caseI = 0; caseI < N; ++caseI) {
		// input
		cin >> n >> m >> s >> t;
		graph.clear();
		for (int i = 0; i < n; ++i)
			graph.push_back(map<int, int>());
		for (int i = 0, a, b, w; i < m; ++i)
			cin >> a >> b >> w, graph[a][b] = graph[b][a] = w;
		// solve
		dijkstra(s);
		cout << "Case #" << (caseI + 1) << ": ";
		if (dijkstraD[t] == numeric_limits<int>::max())
			cout << "unreachable";
		else
			cout << dijkstraD[t];
		cout << endl;
	}
	return 0;
}

681 – Convex Hull Finding


Obviously, a convex hull problem. Tough, make sure that you sort the points w.r.t. y and build the hull in clockwise direction. I used the monotone chain algorithm.

#include <iostream>
#include <algorithm>
#include <complex>
#include <vector>
#include <limits>
using namespace std;

typedef long long gtype;
typedef complex<gtype> point;
#define x real()
#define y imag()
#define crs(a, b) ( (conj(a) * (b)).y )
bool cmp_point(point const& p1, point const& p2) {
	return p1.y == p2.y ? (p1.x < p2.x) : (p1.y < p2.y);
}

vector<point> mcH;
void monotoneChain(vector<point> &p) {
	int n = p.size(), k = 0;
	mcH = vector<point>(2 * n);
	sort(p.begin(), p.end(), cmp_point);
	for (int i = 0; i < n; i++) {
		while (k >= 2 && crs(mcH[k - 1] - mcH[k - 2], p[i] - mcH[k - 2]) <= 0)
			k--;
		mcH[k++] = p[i];
	}
	for (int i = n - 2, t = k + 1; i >= 0; i--) {
		while (k >= t && crs(mcH[k - 1] - mcH[k - 2], p[i] - mcH[k - 2]) <= 0)
			k--;
		mcH[k++] = p[i];
	}
	mcH.resize(k);
}

int main() {
	int nCase, n;
	vector<point> p;
	cin >> nCase;
	cout << nCase << endl;
	while (nCase-- && cin >> n) {
		// input & convex hull
		p.clear(), p.resize(n);
		for (int i = 0; i < n; ++i)
			cin >> p[i].x >> p[i].y;
		monotoneChain(p);
		// output
		cout << mcH.size() << endl;
		for (int i = 0; i < mcH.size(); ++i)
			cout << mcH[i].x << " " << mcH[i].y << endl;
		if (nCase) {
			cin >> n;
			cout << "-1\n";
		}
	}
	return 0;
}

10801 – Lift Hopping


Given a 100-floor building with a number of elevators that are only allowed to stop at certain floors, find the fastest way to reach a given floor.

We can map the building to a graph. A floor is a node and any two floors that are connected by an elevator are two ends of an edge.Find the shortest path and you’re done. Beware that the graph is bidirectional.

#include <algorithm>
#include <limits>
#include <cstdio>
#include <cstring>
#include <queue>
#include <map>
using namespace std;

vector<map<int, int> > graph;
vector<int> dijkstraD, dijkstraP;

void dijkstra(int s) {
	dijkstraD = vector<int>(graph.size(), numeric_limits<int>::max());
	dijkstraP = vector<int>(graph.size(), -1);
	priority_queue<pair<int, int> > q;
	dijkstraP[s] = -s - 1;
	dijkstraD[s] = 0;
	q.push(make_pair(dijkstraD[s], s));
	while (!q.empty()) {
		pair<int, int> p = q.top();
		q.pop();
		if (dijkstraP[p.second] < 0) {
			dijkstraP[p.second] = -dijkstraP[p.second] - 1;
			for (map<int, int>::iterator itr = graph[p.second].begin();
			itr != graph[p.second].end(); ++itr)
				if (dijkstraP[itr->first] < 0
				&& dijkstraD[p.second] + graph[p.second][itr->first] < dijkstraD[itr->first]) {
					dijkstraP[itr->first] = -p.second - 1;
					dijkstraD[itr->first] = dijkstraD[p.second] + graph[p.second][itr->first];
					q.push(pair<int, int>(-dijkstraD[itr->first], itr->first));
				}
		}
	}
}

int main() {
	int n, k, t[8], K = 100;
	char line[1024], *p;
	while (scanf("%d %d", &n, &k) == 2) {
		// build graph
		graph.clear();
		// nodes
		for (int i = n * K; i > -1; --i)
			graph.push_back(map<int, int>());
		// elevator speed
		for (int i = 0; i < n; ++i)
			scanf("%d", &t[i]);
		// changing elevators cost
		for (int i = 1; i < n; ++i)
			graph[K * (i - 1)][K * i] = graph[K * i][K * (i - 1)] = 0;
		for (int j = 1; j < K; ++j)
			for (int i = 0; i < n; ++i)
				for (int i2 = 0; i2 < n; ++i2)
					if (i != i2)
						graph[K * i + j][K * i2 + j] = 60;
		// elevator stop
		gets(line);
		for (int i = 0; i < n; ++i) {
			int prev, cur;
			gets(line);
			p = strtok(line, " ");
			sscanf(p, "%d", &prev);
			while ((p = strtok(NULL, " "))) {
				sscanf(p, "%d", &cur);
				graph[K * i + prev][K * i + cur] =
				graph[K * i + cur][K * i + prev] =
				t[i] * abs(cur - prev);
				prev = cur;
			}
		}
		//
		int d = numeric_limits<int>::max();
		dijkstra(0);
		for (int i = 0; i < n; ++i)
			d = min(d, dijkstraD[K * i + k]);
		if (d == numeric_limits<int>::max())
			printf("IMPOSSIBLE\n");
		else
			printf("%d\n", d);
	}
	return 0;
}

Numerical Tools


An open source SWING piece of software for solving, plotting and interpolating linear/non-linear equations numerically with high efficiency.

RFI-Logo

Features
This piece of software has interactive GUI that enables the user to enter augmented matrices, functions and data and select from different methods and customize the solution steps. The answer for the chosen method gives execution time, iterations, approximate solution, precision and an explanation with the detailed steps of the solution.

Screenshots

Downloads
RFL.zip – Root-finding & interpolation
SSLE.zip – Solving systems of non-linear equations
A detailed user guide is included with each.

Sources
numerical-tools – Google Code SVN