#include "validation.h" #include #include // In this file, you should validate the grammar of your input files. // Any additional constraints mentioned in the problem statement should also be checked here. // Please use the Validator class from the header for verifying the grammar. // This automatically exits with code 43 (WA) when input parsing fails, // and exits with code 42 when reading input and all tests succeeded. // Please use v.WA("some ", "error ", "here ") to exit with code 43 manually. // When your program crashes unexpectedly, or something weird is going on, // please write some info to stderr and return anything different from 42 and 43. using vi = std::vector; struct UnionFind { vi par, rank, size; int c; UnionFind(int n) : par(n), rank(n,0), size(n,1), c(n) { for (int i = 0; i < n; ++i) par[i] = i; } int find(int i) { return (par[i] == i ? i : (par[i] = find(par[i]))); } bool same(int i, int j) { return find(i) == find(j); } int get_size(int i) { return size[find(i)]; } int count() { return c; } void merge(int i, int j) { if ((i = find(i)) == (j = find(j))) return; c--; if (rank[i] > rank[j]) swap(i, j); par[i] = j; size[j] += size[i]; if (rank[i] == rank[j]) rank[j]++; } }; // TODO match these with the problem statement. constexpr int MAXN = 1e5; constexpr int MAXM = 2e5; constexpr int MAXS = 10; constexpr int MAXP = 1e9; constexpr int MAXW = 1e9; constexpr int MAXC = 1e9; int main(int argc, char **argv) { InputValidator v; int n = v.read_int(1, MAXN); v.space(); int m = v.read_int(0, MAXM); v.space(); int s = v.read_int(1, MAXS); v.newline(); long long total_population = 0LL; for (int i = 0; i < n; ++i) { int pi = v.read_int(0, MAXP); total_population += (long long)pi; if (i + 1 < n) v.space(); else v.newline(); } UnionFind uf(n); std::set> st; for (int i = 0; i < m; ++i) { int u1 = v.read_int(1, n); v.space(); int u2 = v.read_int(1, n); v.space(); int w = v.read_int(1, MAXW); v.newline(); u1 -= 1, u2 -= 1; if (u1 > u2) swap(u1, u2); v.assert(u1 != u2, "Self edge on ", u1+1, " at position ", i, "."); v.assert(st.find({u1, u2}) == st.end(), "Double edge from ", u1, " to ", u2, " with second at ", i, "."); st.insert({u1, u2}); uf.merge(u1, u2); } v.assert(uf.count() == 1, "Graph must be connected."); long long total_shelter = 0; std::set ss; for (int i = 0; i < s; ++i) { int si = v.read_int(1, n); v.space(); int ci = v.read_int(1, MAXC); v.newline(); v.assert(ss.find(si) == ss.end(), "Duplicate shelter ", si, "."); total_shelter += ci; } v.assert(total_shelter >= total_population, "Population size cannot be ", "larger than shelter size."); }