Submission #167516

# Submission time Handle Problem Language Result Execution time Memory
167516 2019-12-08T18:17:54 Z faremy Parachute rings (IOI12_rings) C++14
0 / 100
1387 ms 88808 KB
#include <algorithm>
#include <vector>
#include <iostream>


const int MAXN = 1e6;
int rings;

std::vector<int> graph[MAXN];
int parent[MAXN];
int ccSize[MAXN];

int candidate = -1;
int part = 0;
int last = -1;
bool isParticular[MAXN];

std::vector<int> listThree;
std::vector<int> listMore;
bool seen[MAXN];


void Init(int N_)
{
	rings = N_;
	for (int iRing = 0; iRing < rings; iRing++)
	{
		parent[iRing] = iRing;
		ccSize[iRing] = 1;
	}
}

int find(int node)
{
	if (node != parent[node])
		parent[node] = find(parent[node]);
	return parent[node];
}

void fillLists(int node)
{
	if (seen[node])
		return;
	seen[node] = true;

	if (graph[node].size() == 3)
		listThree.emplace_back(node);
	else if (graph[node].size() > 3)
		listMore.emplace_back(node);
	for (int next : graph[node])
		fillLists(next);
}

int nogood(int node, bool isFirst)
{
	if (seen[node])
		return 0;
	seen[node] = true;

	int degOffset = 0;
	for (int next : graph[node])
		if (seen[next])
			degOffset++;

	if (graph[node].size() - degOffset == 2 && !isFirst)
		return -1;

	int ans = (graph[node].size() - degOffset <= isFirst);
	for (int next : graph[node])
	{
		int sub = nogood(next, 0);
		if (sub == -1)
			return -1;
		ans |= sub;
	}

	return ans;
}

int check(int node)
{
	listThree.clear();
	listMore.clear();
	std::fill_n(seen, rings, false);

	fillLists(node);
	if (listThree.empty() && listMore.empty())
		return ccSize[node];

	if (listMore.size() > 1)
	{
		candidate = -2;
		return 0;
	}

	if (listMore.size() == 1)
	{
		std::fill_n(seen, rings, false);
		seen[listMore[0]] = true;
		
		for (int start : graph[listMore[0]])
			if (!seen[start] && nogood(start, 1) < 1)
			{
				candidate = -2;
				return 0;
			}

		return 1;
	}

	if (listThree.size() > 4)
	{
		candidate = -2;
		return 0;
	}

	if (listThree.size() == 1)
	{
		std::fill_n(seen, rings, false);
		seen[listThree[0]] = true;

		int cyc = 0;
		for (int start : graph[listThree[0]])
		{
			if (seen[start])
				cyc++;
			else if (nogood(start, 1) < 1)
			{
				candidate = -2;
				return 0;
			}
		}

		if (cyc == 0)
			return 4;
		if (cyc == 1)
			return 3;
		return 1;
	}

	int ans = 0;
	for (int root : listThree)
	{	
		std::fill_n(seen, rings, false);
		seen[root] = true;

		bool isInvalid = false;
		for (int start : graph[root])
			if (!seen[start])
				isInvalid |= (nogood(start, 1) < 1);
		ans += !isInvalid;
	}

	if (ans == 0)
		candidate = -2;
	return ans;
}

void Link(int A, int B)
{
	if (candidate == -2)
		return;
	int ccA = find(A);
	int ccB = find(B);

	graph[A].emplace_back(B);
	graph[B].emplace_back(A);

	if (ccA == ccB)
	{
		part += !isParticular[ccA];
		isParticular[ccA] = true;
		last = -1;
	}
	else
	{
		if (ccSize[ccA] < ccSize[ccB])
			std::swap(ccA, ccB);
		parent[ccB] = ccA;
		ccSize[ccA] += ccSize[ccB];

		if (isParticular[ccA] && isParticular[ccB])
		{
			part--;
			last = -1;
		}

		isParticular[ccA] |= isParticular[ccB];
		if (graph[A].size() == 3 || graph[A].size() == 4 || graph[B].size() == 3 || graph[B].size() == 4)
		{
			part += !isParticular[ccA];
			isParticular[ccA] = true;
			last = -1;
		}
		else if (graph[A].size() > 4 || graph[B].size() > 4)
		{
			isParticular[ccA] = true;
		}
	}

	if (isParticular[ccA] && candidate != -2)
		candidate = ccA;
}

int CountCritical()
{
	if (candidate == -2)
		return 0;
	if (part == 0)
		return rings;
	if (part > 1)
		return 0;
	//if (last == -1)
		last = check(candidate);
	return last;
}
# Verdict Execution time Memory Grader output
1 Correct 25 ms 23800 KB Output is correct
2 Correct 26 ms 24184 KB Output is correct
3 Correct 27 ms 24184 KB Output is correct
4 Correct 24 ms 23928 KB Output is correct
5 Correct 25 ms 24060 KB Output is correct
6 Correct 27 ms 24316 KB Output is correct
7 Correct 25 ms 23952 KB Output is correct
8 Correct 26 ms 24056 KB Output is correct
9 Correct 27 ms 24184 KB Output is correct
10 Incorrect 26 ms 24056 KB Output isn't correct
# Verdict Execution time Memory Grader output
1 Correct 460 ms 47016 KB Output is correct
2 Correct 939 ms 59192 KB Output is correct
3 Correct 1083 ms 62072 KB Output is correct
4 Correct 1250 ms 67240 KB Output is correct
5 Correct 1291 ms 68116 KB Output is correct
6 Correct 1387 ms 88808 KB Output is correct
7 Correct 1047 ms 61552 KB Output is correct
8 Correct 1159 ms 64588 KB Output is correct
9 Incorrect 1296 ms 67456 KB Output isn't correct
10 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 25 ms 23800 KB Output is correct
2 Correct 26 ms 24184 KB Output is correct
3 Correct 27 ms 24184 KB Output is correct
4 Correct 24 ms 23928 KB Output is correct
5 Correct 25 ms 24060 KB Output is correct
6 Correct 27 ms 24316 KB Output is correct
7 Correct 25 ms 23952 KB Output is correct
8 Correct 26 ms 24056 KB Output is correct
9 Correct 27 ms 24184 KB Output is correct
10 Incorrect 26 ms 24056 KB Output isn't correct
# Verdict Execution time Memory Grader output
1 Correct 25 ms 23800 KB Output is correct
2 Correct 26 ms 24184 KB Output is correct
3 Correct 27 ms 24184 KB Output is correct
4 Correct 24 ms 23928 KB Output is correct
5 Correct 25 ms 24060 KB Output is correct
6 Correct 27 ms 24316 KB Output is correct
7 Correct 25 ms 23952 KB Output is correct
8 Correct 26 ms 24056 KB Output is correct
9 Correct 27 ms 24184 KB Output is correct
10 Incorrect 26 ms 24056 KB Output isn't correct
# Verdict Execution time Memory Grader output
1 Correct 25 ms 23800 KB Output is correct
2 Correct 26 ms 24184 KB Output is correct
3 Correct 27 ms 24184 KB Output is correct
4 Correct 24 ms 23928 KB Output is correct
5 Correct 25 ms 24060 KB Output is correct
6 Correct 27 ms 24316 KB Output is correct
7 Correct 25 ms 23952 KB Output is correct
8 Correct 26 ms 24056 KB Output is correct
9 Correct 27 ms 24184 KB Output is correct
10 Incorrect 26 ms 24056 KB Output isn't correct