Submission #556826

# Submission time Handle Problem Language Result Execution time Memory
556826 2022-05-04T01:56:53 Z blue Towns (IOI15_towns) C++17
100 / 100
17 ms 840 KB
#include "towns.h"
#include <vector>
#include <cmath>
#include <set>
#include <iostream>
#include <cassert>
using namespace std;

namespace
{
	using vi = vector<int>;
	#define sz(x) int(x.size())



	int ST, best_coord;
	vi xcoord;
	int S;
	int T;
	vi distS, dist0;
	int qrc;

}



int best_dist(int i)
{
	int height = (distS[i] + dist0[i] - distS[0])/2;

	return height + abs(xcoord[i] - best_coord);
}

int areequal(int i, int j)
{
	return getDistance(i, j) != best_dist(i) + best_dist(j);

}




const int mx = 110;

struct dsu
{
	vi parent;
	vi subtree;

	dsu()
	{
		parent = subtree = vi(mx);
		for(int i = 0; i < mx; i++)
		{
			parent[i] = i;
			subtree[i] = 1;
		}
	}

	int root(int u)
	{
		if(parent[u] == u) return u;
		else return parent[u] = root(parent[u]);
	}

	void join(int u, int v)
	{
		u = root(u);
		v = root(v);
		if(u == v) return;

		if(subtree[u] < subtree[v]) 
			swap(u, v);

		parent[v] = u;
		subtree[u] += subtree[v];
	}
};


int hubDistance(int N, int sub) 
{
	qrc = 0;
	dist0 = vi(N);
	dist0[0] = 0;
	for(int i = 1; i < N; i++)
		dist0[i] = getDistance(0, i);

	S = 0;
	for(int i = 1; i < N; i++)
		if(dist0[i] > dist0[S])
			S = i;

	ST = 0; //diameter

	// cerr << "done\n";

	distS = vi(N);
	distS[S] = 0;
	distS[0] = dist0[S];

	T = 0;
	ST = distS[0];

	for(int i = 1; i < N; i++)
	{
		if(i != S)
		{
			distS[i] = getDistance(S, i);

			if(distS[i] > ST)
			{
				ST = distS[i];
				T = i;
			}
		}
	}

	// cerr << "S = " << S << "\n";


	vi S0_dist(N);
	for(int i = 0; i < N; i++)
		S0_dist[i] = (distS[i] + dist0[i] - distS[0])/2;

	xcoord = vi(N);
	for(int i = 0; i < N; i++)
		xcoord[i] = distS[i] - S0_dist[i];


	int dist0_ST = (dist0[S] + dist0[T] - ST)/2;

	int ST_0coord = dist0[S] - dist0_ST;

	assert(2*ST_0coord >= distS[T]);


	// assert((dist0[S] + getDistance(0, T) - distS[T]) <= distS[T])

	int res = 5'000'000;
	set<int> best_coords;


	for(int i = 0; i < N; i++)
	{
		if(xcoord[i] > ST_0coord) 
			continue;

		int curr = max(xcoord[i], ST - xcoord[i]);

		if(curr < res)
		{
			res = curr;
			best_coords.clear();
		}

		if(curr == res)
		{
			best_coords.insert(xcoord[i]);
		}

	}


	if(sz(best_coords) == 1)
	{
		best_coord = *best_coords.begin();
	}
	else
	{
		int leftcount = 0;
		for(int i = 0; i < N; i++)
		{
			if(xcoord[i] <= *best_coords.begin())
				leftcount++;
		}

		if(2*leftcount >= N)
			best_coord = *best_coords.begin();
		else 
			best_coord = *best_coords.rbegin();
	}

	// return -res;



	dsu DSU;

	bool balanced = 1;

	int candidate = -1;
	int counter = 0;

	for(int i = 0; i < N; i++)
	{
		if(counter == 0)
		{
			candidate = i;
			counter = 1;
		}
		else
		{
			if(areequal(i, candidate))
			{
				counter++;
				DSU.join(i, candidate);
			}
			else
			{
				counter--;
			}
		}
	}

	vi checked(N, 0);

	checked[DSU.root(candidate)] = 0;

	for(int i = 0; i < N; i++)
	{
		if(checked[DSU.root(i)] == 0)
		{
			if(areequal(DSU.root(i), candidate))
				checked[DSU.root(i)] = 1;
			else
				checked[DSU.root(i)] = -1;
		}
	}

	int ct = 0;
	for(int i = 0; i < N; i++)
		ct += (checked[DSU.root(i)] == 1);

	balanced = (2*ct <= N);



	int R = res;

	if(balanced)
		return R;
	else
		return -R;
}

Compilation message

towns.cpp: In function 'int hubDistance(int, int)':
towns.cpp:81:28: warning: unused parameter 'sub' [-Wunused-parameter]
   81 | int hubDistance(int N, int sub)
      |                        ~~~~^~~
# Verdict Execution time Memory Grader output
1 Correct 11 ms 352 KB Output is correct
2 Correct 9 ms 360 KB Output is correct
3 Correct 1 ms 212 KB Output is correct
4 Correct 13 ms 352 KB Output is correct
5 Correct 13 ms 340 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 340 KB Output is correct
2 Correct 10 ms 340 KB Output is correct
3 Correct 13 ms 352 KB Output is correct
4 Correct 13 ms 340 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 9 ms 360 KB Output is correct
2 Correct 14 ms 340 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 13 ms 340 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 14 ms 340 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 10 ms 352 KB Output is correct
2 Correct 13 ms 348 KB Output is correct
3 Correct 15 ms 348 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 10 ms 340 KB Output is correct
2 Correct 13 ms 460 KB Output is correct
3 Correct 17 ms 840 KB Output is correct