Submission #3664624


Source Code Expand

#include <stdexcept>
#include <cmath>
#include <limits>
#include <type_traits>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#include <utility>
#include <cstddef>
namespace loquat {
using vertex_t = size_t;
}
namespace loquat {
namespace edge_param {
struct to_ {
	vertex_t to;
	explicit to_(vertex_t t = 0)
		: to(t)
	{ }
};
template <typename T>
struct weight_ {
	using weight_type = T;
	weight_type weight;
	weight_(const weight_<T>& w)
		: weight(w.weight)
	{ }
	explicit weight_(const weight_type& w = weight_type())
		: weight(w)
	{ }
};
template <typename T>
using weight = weight_<T>;
template <typename T>
struct capacity_ {
	using capacity_type = T;
	capacity_type capacity;
	explicit capacity_(const capacity_type& c = capacity_type())
		: capacity(c)
	{ }
};
template <typename T>
using capacity = capacity_<T>;
}
namespace detail {
template <typename T, typename... Params>
struct edge_param_wrapper : public T, edge_param_wrapper<Params...> {
	using self_type = edge_param_wrapper<T, Params...>;
	using next_type = edge_param_wrapper<Params...>;
	edge_param_wrapper(const self_type& e)
		: T(static_cast<const T&>(e))
		, next_type(static_cast<const next_type&>(e))
	{ }
	template <typename U, typename... Args>
	explicit edge_param_wrapper(U&& x, Args&&... args)
		: T(std::forward<U>(x))
		, edge_param_wrapper<Params...>(std::forward<Args>(args)...)
	{ }
};
template <typename T>
struct edge_param_wrapper<T> : public T {
	using self_type = edge_param_wrapper<T>;
	edge_param_wrapper(const self_type& e)
		: T(e)
	{ }
	template <typename U>
	explicit edge_param_wrapper(U&& x)
		: T(std::forward<U>(x))
	{ }
};
}
template <typename... Params>
struct edge : public detail::edge_param_wrapper<edge_param::to_, Params...> {
	using self_type = edge<Params...>;
	using wrapper_type = detail::edge_param_wrapper<edge_param::to_, Params...>;
	edge(const self_type& e)
		: wrapper_type(static_cast<const wrapper_type&>(e))
	{ }
	template <typename... Args>
	explicit edge(vertex_t to, Args&&... rest)
		: wrapper_type(to, std::forward<Args>(rest)...)
	{ }
};
}
namespace loquat {
template <typename EdgeType>
struct has_weight {
private:
	template <typename U>
	static std::true_type check_type(typename U::weight_type *);
	template <typename U>
	static auto check_member(const U& x)
		-> decltype(x.weight, std::true_type());
public:
	static const bool value =
		decltype(check_type<EdgeType>(nullptr))::value &&
		decltype(check_member(std::declval<EdgeType>()))::value;
};
}
namespace loquat {
template <typename EdgeType>
class adjacency_list {
public:
	using edge_type = EdgeType;
	using edge_list = std::vector<edge_type>;
private:
	std::vector<std::vector<EdgeType>> m_edges;
public:
	explicit adjacency_list(size_t n)
		: m_edges(n)
	{ }
	size_t size() const {
		return m_edges.size();
	}
	const edge_list& operator[](vertex_t u) const {
		return m_edges[u];
	}
	edge_list& operator[](vertex_t u){
		return m_edges[u];
	}
	template <typename... Args>
	void add_edge(vertex_t from, Args&&... args){
		m_edges[from].emplace_back(std::forward<Args>(args)...);
	}
	void add_edge(vertex_t from, const edge_type& e){
		m_edges[from].emplace_back(e);
	}
};
}
namespace loquat {
namespace detail {
template <typename EdgeType>
auto negate_weight(EdgeType& e)
	-> typename std::enable_if<has_weight<EdgeType>::value, void>::type
{
	e.weight = -e.weight;
}
}
template <typename EdgeType>
struct residual_edge : public EdgeType {
	using base_type = EdgeType;
	size_t rev;
	residual_edge(const base_type& e, size_t rev)
		: base_type(e)
		, rev(rev)
	{ }
};
template <typename EdgeType>
adjacency_list<residual_edge<EdgeType>>
make_residual(const adjacency_list<EdgeType>& graph){
	using edge_type = EdgeType;
	using residual_type = residual_edge<edge_type>;
	using capacity_type = typename edge_type::capacity_type;
	const size_t n = graph.size();
	adjacency_list<residual_type> result(n);
	for(vertex_t u = 0; u < n; ++u){
		for(const auto& e : graph[u]){
			result.add_edge(u, residual_type(e, 0));
		}
	}
	for(vertex_t u = 0; u < n; ++u){
		const size_t m = graph[u].size();
		for(size_t i = 0; i < m; ++i){
			auto e = graph[u][i];
			const auto v = e.to;
			e.to = u;
			e.capacity = capacity_type();
			detail::negate_weight(e);
			result[u][i].rev = result[v].size();
			result.add_edge(v, residual_type(e, i));
		}
	}
	return result;
}
}
namespace loquat {
template <typename EdgeType, typename Predicate>
adjacency_list<EdgeType> filter(
	const adjacency_list<EdgeType>& graph,
	Predicate pred)
{
	const size_t n = graph.size();
	adjacency_list<EdgeType> result(n);
	for(vertex_t u = 0; u < n; ++u){
		for(const auto& e : graph[u]){
			if(pred(u, e)){ result.add_edge(u, e); }
		}
	}
	return result;
}
}
namespace loquat {
template <typename T>
constexpr inline auto positive_infinity() noexcept
	-> typename std::enable_if<std::is_integral<T>::value, T>::type
{
	return std::numeric_limits<T>::max();
}
template <typename T>
constexpr inline auto is_positive_infinity(T x) noexcept
	-> typename std::enable_if<std::is_integral<T>::value, bool>::type
{
	return x == std::numeric_limits<T>::max();
}
}
namespace loquat {
class no_solution_error : public std::runtime_error {
public:
	explicit no_solution_error(const char *what)
		: std::runtime_error(what)
	{ }
};
}
namespace loquat {
template <typename EdgeType>
std::vector<typename EdgeType::weight_type>
sssp_bellman_ford(vertex_t source, const adjacency_list<EdgeType>& graph){
	using weight_type = typename EdgeType::weight_type;
	const auto inf = positive_infinity<weight_type>();
	const auto n = graph.size();
	std::vector<weight_type> result(n, inf);
	result[source] = weight_type();
	bool finished = false;
	for(size_t iter = 0; !finished && iter < n; ++iter){
		finished = true;
		for(loquat::vertex_t u = 0; u < n; ++u){
			if(loquat::is_positive_infinity(result[u])){ continue; }
			for(const auto& e : graph[u]){
				const auto v = e.to;
				if((result[u] + e.weight) < result[v]){
					result[v] = result[u] + e.weight;
					finished = false;
				}
			}
		}
	}
	if(!finished){
		throw no_solution_error("graph has a negative cycle");
	}
	return result;
}
}
namespace loquat {
template <typename EdgeType>
typename EdgeType::weight_type
mincostflow_primal_dual(
	typename EdgeType::capacity_type flow,
	vertex_t source,
	vertex_t sink,
	adjacency_list<EdgeType>& graph)
{
	using edge_type = EdgeType;
	using weight_type = typename edge_type::weight_type;
	const auto inf = positive_infinity<weight_type>();
	const auto n = graph.size();
	const auto predicate =
		[](vertex_t, const edge_type& e) -> bool { return e.capacity > 0; };
	auto h = sssp_bellman_ford(source, filter(graph, predicate));
	std::vector<vertex_t> prev_vertex(n);
	std::vector<size_t> prev_edge(n);
	weight_type result = 0;
	while(flow > 0){
		using pair_type = std::pair<weight_type, vertex_t>;
		std::priority_queue<
			pair_type, std::vector<pair_type>, std::greater<pair_type>> pq;
		std::vector<weight_type> d(n, inf);
		pq.emplace(0, source);
		d[source] = weight_type();
		while(!pq.empty()){
			const auto p = pq.top();
			pq.pop();
			const auto u = p.second;
			if(d[u] < p.first){ continue; }
			for(size_t i = 0; i < graph[u].size(); ++i){
				const auto& e = graph[u][i];
				if(e.capacity <= 0){ continue; }
				const auto v = e.to;
				const auto t = d[u] + e.weight + h[u] - h[v];
				if(d[v] <= t){ continue; }
				d[v] = t;
				prev_vertex[v] = u;
				prev_edge[v] = i;
				pq.emplace(t, v);
			}
		}
		if(is_positive_infinity(d[sink])){
			throw no_solution_error("there are no enough capacities to flow");
		}
		for(size_t i = 0; i < n; ++i){ h[i] += d[i]; }
		weight_type f = flow;
		for(vertex_t v = sink; v != source; v = prev_vertex[v]){
			const auto u = prev_vertex[v];
			f = std::min(f, graph[u][prev_edge[v]].capacity);
		}
		flow -= f;
		result += f * h[sink];
		for(vertex_t v = sink; v != source; v = prev_vertex[v]){
			const auto u = prev_vertex[v];
			auto& e = graph[u][prev_edge[v]];
			e.capacity -= f;
			graph[v][e.rev].capacity += f;
		}
	}
	return result;
}
}
using namespace std;
using edge = loquat::edge<
	loquat::edge_param::weight<int>,
	loquat::edge_param::capacity<int>>;
int main(){
	ios_base::sync_with_stdio(false);
	int n, k;
	cin >> n >> k;
	vector<int> a(n), b(n);
	for(int i = 0; i < n; ++i){ cin >> a[i]; --a[i]; }
	for(int i = 0; i < n; ++i){ cin >> b[i]; --b[i]; }
	vector<vector<int>> conn(n);
	vector<int> usage(n);
	int score = 0;
	for(int i = 0; i < n; ++i){
		const int u = max(a[i], b[i]);
		const int v = min(a[i], b[i]);
		conn[u].push_back(v);
		++usage[u];
		score += u + 1;
	}
	int variations = 0;
	for(int i = 0; i < n; ++i){
		if(usage[i] >= 1){ ++variations; }
	}
	if(variations >= k){
		cout << score << endl;
		return 0;
	}
	loquat::adjacency_list<edge> g(2 * n + 2);
	const int source = 2 * n, sink = source + 1;
	for(int r = 0; r < n; ++r){
		if(usage[r] == 1){
			continue;
		}else if(usage[r] == 0){
			g.add_edge(r + n, sink, 0, 1);
			continue;
		}else{
			vector<bool> vis(n);
			vis[r] = true;
			for(int u = n - 1; u >= 0; --u){
				if(!vis[u]){ continue; }
				for(const int v : conn[u]){ vis[v] = true; }
			}
			for(int i = 0; i < r; ++i){
				if(!vis[i]){ continue; }
				g.add_edge(r, i + n, r - i, 1);
			}
			g.add_edge(source, r, 0, usage[r] - 1);
		}
	}
	auto residual = loquat::make_residual(g);
	score -= loquat::mincostflow_primal_dual(k - variations, source, sink, residual);
	cout << score << endl;
	return 0;
}

Submission Info

Submission Time
Task G - Sum of Cards
User logicmachine
Language C++14 (GCC 5.4.1)
Score 500
Code Size 9872 Byte
Status AC
Exec Time 1155 ms
Memory 2304 KB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 500 / 500
Status
AC × 3
AC × 43
Set Name Test Cases
Sample s1.txt, s2.txt, s3.txt
All 01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, 19.txt, 20.txt, 21.txt, 22.txt, 23.txt, 24.txt, 25.txt, 26.txt, 27.txt, 28.txt, 29.txt, 30.txt, 31.txt, 32.txt, 33.txt, 34.txt, 35.txt, 36.txt, 37.txt, 38.txt, 39.txt, 40.txt, s1.txt, s2.txt, s3.txt
Case Name Status Exec Time Memory
01.txt AC 1 ms 256 KB
02.txt AC 1 ms 256 KB
03.txt AC 1 ms 256 KB
04.txt AC 1 ms 256 KB
05.txt AC 1 ms 256 KB
06.txt AC 1 ms 256 KB
07.txt AC 4 ms 384 KB
08.txt AC 1 ms 256 KB
09.txt AC 1 ms 256 KB
10.txt AC 2 ms 384 KB
11.txt AC 1 ms 256 KB
12.txt AC 2 ms 384 KB
13.txt AC 1 ms 256 KB
14.txt AC 3 ms 384 KB
15.txt AC 2 ms 384 KB
16.txt AC 2 ms 512 KB
17.txt AC 538 ms 1920 KB
18.txt AC 2 ms 512 KB
19.txt AC 732 ms 2048 KB
20.txt AC 1155 ms 2304 KB
21.txt AC 2 ms 512 KB
22.txt AC 2 ms 512 KB
23.txt AC 2 ms 512 KB
24.txt AC 2 ms 512 KB
25.txt AC 813 ms 2048 KB
26.txt AC 993 ms 2176 KB
27.txt AC 2 ms 512 KB
28.txt AC 2 ms 512 KB
29.txt AC 2 ms 512 KB
30.txt AC 2 ms 512 KB
31.txt AC 2 ms 512 KB
32.txt AC 247 ms 2176 KB
33.txt AC 2 ms 512 KB
34.txt AC 2 ms 512 KB
35.txt AC 2 ms 512 KB
36.txt AC 2 ms 512 KB
37.txt AC 226 ms 2048 KB
38.txt AC 1105 ms 2176 KB
39.txt AC 2 ms 512 KB
40.txt AC 2 ms 512 KB
s1.txt AC 1 ms 256 KB
s2.txt AC 1 ms 256 KB
s3.txt AC 1 ms 256 KB