CSES - TCR Contest - Results
Submission details
Task:Movies
Sender:KnowYourArchitecture
Submission time:2017-11-21 19:47:14 +0200
Language:C++
Status:READY
Result:ACCEPTED
Test results
testverdicttime
#1ACCEPTED0.07 sdetails
#2ACCEPTED0.06 sdetails
#3ACCEPTED0.06 sdetails
#4ACCEPTED0.07 sdetails
#5ACCEPTED0.07 sdetails

Code

#include <bits/stdc++.h>
#define F first
#define S second
using namespace std;
typedef long long ll;
const ll inf=1e18;
template<int V, int E> struct MinCostFlow {
	struct Edge {
		int a, b;
		ll ca, co;
	} es[E*2];
	int eu=0, nmz=0;
	vector<int> g[V+1];
	ll p[V+1], d[V+1];
	int fr[V+1], u[V+1];
	void addEdge(int a, int b, ll ca, ll co) {
		nmz = 0;
		es[eu++] = {a, b, ca, co};
		es[eu++] = {b, a, 0, -co};
		g[a].push_back(eu-2);
		g[b].push_back(eu-1);
	}
	void normalize(int source) {
		if (nmz) return; nmz=1;
		for (int i = 1; i <= V; i++) {
			p[i] = inf; u[i] = 0;
		}
		p[source] = 0;
		queue<int> q;q.push(source);
		while(!q.empty()) {
			int x=q.front();
			u[x]=0;q.pop();
			for (int e:g[x]) {
				if (es[e].ca>0 && p[x]+es[e].co<p[es[e].b]) {
					p[es[e].b]=p[x]+es[e].co;
					if (!u[es[e].b]) {
						u[es[e].b] = 1;
						q.push(es[e].b);
					}
				}
			}
		}
	}
	ll augment(int x, ll fl) {
		if (fr[x]==-1) return fl;
		ll r=augment(es[fr[x]].a, min(fl, es[fr[x]].ca));
		es[fr[x]].ca-=r;
		es[fr[x]^1].ca+=r;
		return r;
	}
	pair<ll, ll> flow(int source, int sink, ll mf) {
		priority_queue<pair<ll, int>> dij;
		for (int i = 1; i <= V; i++) {
			u[i]=0; fr[i]=-1; d[i]=inf;
		}
		d[source]=0;
		dij.push({0, source});
		while (!dij.empty()) {
			auto x=dij.top(); dij.pop();
			if (u[x.S]) continue;
			u[x.S]=1;
			for (int e:g[x.S]) {
				ll nd=d[x.S]+es[e].co+p[x.S]-p[es[e].b];
				if (es[e].ca>0 && nd<d[es[e].b]) {
					d[es[e].b]=nd;
					fr[es[e].b]=e;
					dij.push({-nd, es[e].b});
				}
			}
		}
		ll co=d[sink]+p[sink];
		for (int i = 1;i<=V;i++) {
			if (fr[i]!=-1) p[i]+=d[i];
		}
		if (u[sink]) {
			ll fl=augment(sink, mf);
			return {fl, fl*co};
		}
		else return {0, 0};
	}
	pair<ll, ll> getKFlow(int source, int sink, ll k) {
		ll fl=0; ll co=0;
		normalize(source);
		while (1) {
			pair<ll, ll> t=flow(source, sink, k);
			fl+=t.F; k-=t.F; co+=t.S;
			if (k==0||t.F==0) break;
		}
		return {fl, co};
	}
};

int main() {
	int n;
	cin >> n;
	MinCostFlow<222, 33333> mcf;
	for (int i = 0; i < n; i++) {
		mcf.addEdge(1, i+3, 1, 0);
		mcf.addEdge(i+104, 2, 1, 0);
		for (int j = 0; j < n; j++) {
			int cost;
			cin >> cost;
			mcf.addEdge(i+3, j+104, 1, cost);
		}
	}

	auto res = mcf.getKFlow(1, 2, inf);

	cout << res.S << endl;
}

Test details

Test 1

Verdict: ACCEPTED

input
100
775 304 507 693 578 381 114 26...

correct output
1608

user output
1608

Test 2

Verdict: ACCEPTED

input
100
185 349 73 411 112 25 72 275 2...

correct output
1544

user output
1544

Test 3

Verdict: ACCEPTED

input
100
304 100 475 782 692 439 659 26...

correct output
1844

user output
1844

Test 4

Verdict: ACCEPTED

input
100
81 785 426 43 886 714 87 737 3...

correct output
1866

user output
1866

Test 5

Verdict: ACCEPTED

input
100
944 524 622 966 995 212 173 78...

correct output
1440

user output
1440