Submission #383840

#TimeUsernameProblemLanguageResultExecution timeMemory
383840LucaDantasTowns (IOI15_towns)C++17
13 / 100
265 ms444 KiB
#include "towns.h"
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cassert>
#include <vector>
#include <map>

constexpr int maxn = 120;

int dp[maxn][maxn], c[maxn];

std::map<int, std::vector<int>> filhos;

int get(int i, int j) {
	if(i > j) std::swap(i, j);
	return dp[i][j] != -1 ? dp[i][j] : dp[i][j] = getDistance(i, j);
}

struct DSU
{
	int pai[maxn], peso[maxn];
	void init() { for(int i = 0; i < maxn; i++) pai[i] = i, peso[i] = 1; }
	int find(int x) { return pai[x]==x?x:pai[x]=find(pai[x]); }
	void join(int a, int b) {
		a = find(a), b = find(b);
		if(a == b) return;
		if(peso[a] < peso[b])
			std::swap(a, b);
		pai[b] = a;
		peso[a] += peso[b];
	}
	int sz(int x) { return peso[find(x)]; }
} dsu;

int hubDistance(int N, int sub) {
	memset(dp, -1, sizeof dp);
	memset(c, 0, sizeof c);
	dsu.init();
	filhos.clear();
	int a = 0, b = 0, dist = 0;
	for(int i = 0; i < 2; i++) {
		for(int j = 0; j < N; j++) {
			if(a != j) {
				int v = get(a, j);
				if(v > dist) b = j, dist = v;
			}
		}
		if(!i) a = b, dist = 0, b = 0;
	}
	int R = 0x3f3f3f3f;
	for(int i = 0; i < N; i++) {
		if(i == a || i == b) continue;
		int d1 = get(a, i), d2 = get(b, i);
		c[i] = (d1 + d2 - dist) >> 1;
		R = std::min(R, std::max(d1, d2) - c[i]);
	}
	// if(sub <= 2) return R;
	for(a = 0; a < N; a++) {
		for(b = a+1; b < N; b++) {
			filhos.clear();
			for(int i = 0; i < N; i++) {
				if(i == a || i == b) continue;
				int d1 = get(a, i), d2 = get(b, i);
				c[i] = (d1 + d2 - dist) >> 1;
				filhos[d1-c[i]].push_back(i);
			}

			if(filhos.count(R) && filhos.count(dist - R)) return R;
			int sz = 1;

			bool ok = 0;
			for(auto it : filhos) {
				if(it.first != R && it.first != dist - R) {
					sz += (int)(it.second).size();
					continue;
				}
				std::vector<int> v = (it.second);
				int n = (int)v.size();
				if(sz > (N >> 1) || N - sz - n > (N >> 1)) continue;
				for(int i = 0; i < n; i++)
					for(int j = i+1; j < n; j++)
						if(get(v[i], v[j]) != c[v[i]] + c[v[j]])
							dsu.join(v[i], v[j]);
				ok = 1;
				for(int i = 0; i < n; i++)
					if(dsu.sz(v[i]) > (N >> 1)) ok = 0;
				sz += n;
			}

			if(ok == 1) return R;
		}
	}
	return -R;
	// return R * (ok?1:-1);
}

Compilation message (stderr)

towns.cpp: In function 'int hubDistance(int, int)':
towns.cpp:36:28: warning: unused parameter 'sub' [-Wunused-parameter]
   36 | int hubDistance(int N, int sub) {
      |                        ~~~~^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...