Untitled
unknown
c_cpp
2 years ago
19 kB
7
Indexable
#include <algorithm>
#include <cstring>
#include <initializer_list>
#include <iostream>
#include <sstream>
#include <stdexcept>
template< typename T >
class Vector
{
public:
Vector();
Vector(std::initializer_list< T > init);
Vector(const Vector& other);
Vector(Vector&& other) noexcept;
explicit Vector(const T& value);
explicit Vector(size_t size, const T& value);
Vector(T* first, T* last);
~Vector();
Vector& operator=(const Vector& other);
Vector& operator=(Vector&& other) noexcept;
T& operator[](size_t index);
const T& operator[](size_t index) const;
bool operator==(const Vector& other) const;
bool operator!=(const Vector& other) const;
void push_back(const T& value);
void push_back(T&& value);
void pop_back();
void clear();
size_t size() const;
size_t capacity() const;
bool empty() const;
void reserve(size_t newCapacity);
T* begin();
T* end();
const T* begin() const;
const T* end() const;
private:
void reallocate(size_t newCapacity);
T* data_;
size_t size_;
size_t capacity_;
};
template< typename T >
Vector< T >::Vector() : data_(nullptr), size_(0), capacity_(0)
{
// Empty body.
}
template< typename T >
Vector< T >::Vector(std::initializer_list< T > init) : Vector()
{
for (const T& item : init)
{
push_back(item);
}
}
template< typename T >
Vector< T >::Vector(const Vector& other) : data_(nullptr), size_(0), capacity_(0)
{
reallocate(other.capacity_);
size_ = other.size_;
for (size_t i = 0; i < size_; ++i)
{
data_[i] = other.data_[i];
}
}
template< typename T >
Vector< T >::Vector(Vector&& other) noexcept : data_(other.data_), size_(other.size_), capacity_(other.capacity_)
{
other.data_ = nullptr;
other.size_ = 0;
other.capacity_ = 0;
}
template< typename T >
Vector< T >::Vector(const T& value) : data_(new T[value]), size_(value), capacity_(value)
{
for (size_t i = 0; i < size_; ++i)
{
data_[i] = value;
}
}
template< typename T >
Vector< T >::Vector(size_t size, const T& value) : data_(new T[size]), size_(size), capacity_(size)
{
for (size_t i = 0; i < size_; ++i)
{
data_[i] = value;
}
}
template< typename T >
Vector< T >::Vector(T* first, T* last)
{
size_ = last - first;
capacity_ = size_;
data_ = new T[capacity_];
std::copy(first, last, data_);
}
template< typename T >
Vector< T >::~Vector()
{
delete[] data_;
}
template< typename T >
Vector< T >& Vector< T >::operator=(const Vector& other)
{
if (this != &other)
{
delete[] data_;
reallocate(other.capacity_);
size_ = other.size_;
for (size_t i = 0; i < size_; ++i)
{
data_[i] = other.data_[i];
}
}
return *this;
}
template< typename T >
Vector< T >& Vector< T >::operator=(Vector&& other) noexcept
{
if (this != &other)
{
delete[] data_;
data_ = other.data_;
size_ = other.size_;
capacity_ = other.capacity_;
other.data_ = nullptr;
other.size_ = 0;
other.capacity_ = 0;
}
return *this;
}
template< typename T >
T& Vector< T >::operator[](size_t index)
{
if (index >= size_)
{
throw std::out_of_range("Index out of range!");
}
return data_[index];
}
template< typename T >
const T& Vector< T >::operator[](size_t index) const
{
if (index >= size_)
{
throw std::out_of_range("Index out of range!");
}
return data_[index];
}
template< typename T >
bool Vector< T >::operator==(const Vector& other) const
{
if (size_ != other.size_)
{
return false;
}
for (size_t i = 0; i < size_; ++i)
{
if (data_[i] != other.data_[i])
{
return false;
}
}
return true;
}
template< typename T >
bool Vector< T >::operator!=(const Vector& other) const
{
return !(*this == other);
}
template< typename T >
void Vector< T >::push_back(const T& value)
{
if (size_ >= capacity_)
{
reallocate(capacity_ == 0 ? 1 : 2 * capacity_);
}
data_[size_++] = value;
}
template< typename T >
void Vector< T >::push_back(T&& value)
{
if (size_ >= capacity_)
{
reallocate(capacity_ == 0 ? 1 : 2 * capacity_);
}
data_[size_++] = std::move(value);
}
template< typename T >
void Vector< T >::pop_back()
{
if (size_ > 0)
{
--size_;
}
}
template< typename T >
void Vector< T >::clear()
{
size_ = 0;
}
template< typename T >
size_t Vector< T >::size() const
{
return size_;
}
template< typename T >
size_t Vector< T >::capacity() const
{
return capacity_;
}
template< typename T >
bool Vector< T >::empty() const
{
return size_ == 0;
}
template< typename T >
void Vector< T >::reserve(size_t newCapacity)
{
if (newCapacity > capacity_)
{
reallocate(newCapacity);
}
}
template< typename T >
T* Vector< T >::begin()
{
return data_;
}
template< typename T >
T* Vector< T >::end()
{
return data_ + size_;
}
template< typename T >
const T* Vector< T >::begin() const
{
return data_;
}
template< typename T >
const T* Vector< T >::end() const
{
return data_ + size_;
}
template< typename T >
void Vector< T >::reallocate(size_t newCapacity)
{
T* newData = new T[newCapacity];
for (size_t i = 0; i < size_; ++i)
{
newData[i] = std::move(data_[i]);
}
delete[] data_;
data_ = newData;
capacity_ = newCapacity;
}
template< typename T, typename Container = Vector< T > >
class Queue
{
public:
Queue() = default;
T& front();
const T& front() const;
T& back();
const T& back() const;
void push(const T& value);
void push(T&& value);
void pop();
bool empty() const;
size_t size() const;
private:
Container container;
};
template< typename T, typename Container >
T& Queue< T, Container >::front()
{
return container[0];
}
template< typename T, typename Container >
const T& Queue< T, Container >::front() const
{
return container[0];
}
template< typename T, typename Container >
T& Queue< T, Container >::back()
{
return container[container.size() - 1];
}
template< typename T, typename Container >
const T& Queue< T, Container >::back() const
{
return container[container.size() - 1];
}
template< typename T, typename Container >
void Queue< T, Container >::push(const T& value)
{
container.push_back(value);
}
template< typename T, typename Container >
void Queue< T, Container >::push(T&& value)
{
container.push_back(std::move(value));
}
template< typename T, typename Container >
void Queue< T, Container >::pop()
{
if (!container.empty())
{
for (size_t i = 1; i < container.size(); ++i)
{
container[i - 1] = std::move(container[i]);
}
container.pop_back();
}
}
template< typename T, typename Container >
bool Queue< T, Container >::empty() const
{
return container.empty();
}
template< typename T, typename Container >
size_t Queue< T, Container >::size() const
{
return container.size();
}
class String
{
public:
String();
explicit String(const char* str);
~String();
String& operator=(const String& other);
char& operator[](size_t index);
const char& operator[](size_t index) const;
String& operator=(const char* str);
String& operator+=(char c);
size_t length() const;
const char* c_str() const;
friend std::ostream& operator<<(std::ostream& os, const String& str)
{
if (str.buffer_ != nullptr)
{
os << str.buffer_;
}
return os;
}
friend void readLine(std::istream& is, String& str)
{
char c;
str = "";
while (is.get(c) && c != '\n')
{
str += c;
}
}
private:
char* buffer_;
};
String::String() : buffer_(nullptr)
{
// Empty body.
}
String::String(const char* str)
{
if (str != nullptr)
{
buffer_ = new char[strlen(str) + 1];
strcpy(buffer_, str);
}
else
{
buffer_ = nullptr;
}
}
String::~String()
{
delete[] buffer_;
}
String& String::operator=(const String& other)
{
if (this != &other)
{
delete[] buffer_;
if (other.buffer_ != nullptr)
{
buffer_ = new char[strlen(other.buffer_) + 1];
strcpy(buffer_, other.buffer_);
}
else
{
buffer_ = nullptr;
}
}
return *this;
}
char& String::operator[](size_t index)
{
if (buffer_ != nullptr && index < strlen(buffer_))
{
return buffer_[index];
}
else
{
std::cerr << "Index out of range\n";
exit(1);
}
}
const char& String::operator[](size_t index) const
{
if (buffer_ != nullptr && index < strlen(buffer_))
{
return buffer_[index];
}
else
{
std::cerr << "Index out of range\n";
exit(1);
}
}
String& String::operator=(const char* str)
{
if (buffer_ != nullptr)
{
delete[] buffer_;
}
if (str != nullptr)
{
buffer_ = new char[strlen(str) + 1];
strcpy(buffer_, str);
}
else
{
buffer_ = nullptr;
}
return *this;
}
String& String::operator+=(char c)
{
size_t newLength = length() + 1;
char* newBuffer = new char[newLength + 1];
if (buffer_ != nullptr)
{
strcpy(newBuffer, buffer_);
newBuffer[newLength - 1] = c;
newBuffer[newLength] = '\0';
delete[] buffer_;
}
else
{
newBuffer[0] = c;
newBuffer[1] = '\0';
}
buffer_ = newBuffer;
return *this;
}
size_t String::length() const
{
return (buffer_ != nullptr) ? strlen(buffer_) : 0;
}
const char* String::c_str() const
{
return buffer_;
}
using Adjacency = Vector< int >;
class Graph
{
public:
Graph() : number_of_vertices(0)
{
// Empty body.
}
explicit Graph(int vertices) : number_of_vertices(vertices)
{
for (int i = 0; i < number_of_vertices; ++i)
{
adjacency_list.push_back(Adjacency{});
}
}
void addEdge(const int& u, const Adjacency& adj);
Vector< int > degreeSequence();
int countComponents();
char isBipartite();
Vector< int > eccentricity();
Vector< int > greedyColoring();
Vector< int > lfColoring();
int countComplementsEdges();
private:
void depthSearch(int v, Vector< bool >& visited);
int number_of_vertices;
Vector< Adjacency > adjacency_list;
};
void Graph::addEdge(const int& u, const Adjacency& adj)
{
adjacency_list[u] = adj;
}
Vector< int > Graph::degreeSequence()
{
Vector< int > degrees(number_of_vertices);
for (int i = 0; i < number_of_vertices; ++i)
{
degrees[i] = static_cast<int>(adjacency_list[i].size());
}
return degrees;
}
int Graph::countComponents()
{
int components{ 0 };
Vector< bool > visited(number_of_vertices, false);
for (int v = 0; v < number_of_vertices; ++v)
{
if (!visited[v])
{
++components;
depthSearch(v, visited);
}
}
return components;
}
char Graph::isBipartite()
{
Vector< int > colours(number_of_vertices, -1);
Queue< std::pair< int, int > > queueColours;
for (int i = 0; i < number_of_vertices; ++i)
{
if (colours[i] == -1)
{
queueColours.push({ i, 0 });
colours[i] = 0;
while (!queueColours.empty())
{
auto pair = queueColours.front();
queueColours.pop();
int v = pair.first;
int c = pair.second;
for (int j : adjacency_list[v])
{
if (colours[j] == c)
{
return 'F';
}
if (colours[j] == -1)
{
colours[j] = !c;
queueColours.push({ j, colours[j] });
}
}
}
}
}
return 'T';
}
Vector< int > Graph::eccentricity()
{
Vector< int > eccentricities(number_of_vertices, 0);
const int adjustLevel = 1;
for (int v = 0; v < number_of_vertices; ++v)
{
Queue< int > queue;
Vector< bool > visited(number_of_vertices, false);
queue.push(v);
visited[v] = true;
int level = 0;
while (!queue.empty())
{
int size = static_cast<int>(queue.size());
while (size--)
{
int curr = queue.front();
queue.pop();
eccentricities[v] = std::max(eccentricities[v], level);
for (int neighbour : adjacency_list[curr])
{
if (!visited[neighbour])
{
queue.push(neighbour);
visited[neighbour] = true;
}
}
}
++level;
}
eccentricities[v] = level - adjustLevel;
}
return eccentricities;
}
Vector< int > Graph::greedyColoring()
{
Vector< int > verticesColours(number_of_vertices, -1);
Vector< bool > availableColours(number_of_vertices, true);
for (int u = 0; u < number_of_vertices; ++u)
{
for (const auto& neighbour : adjacency_list[u])
{
if (verticesColours[neighbour] != -1)
{
availableColours[verticesColours[neighbour]] = false;
}
}
int colour = 1;
for (; colour < number_of_vertices; ++colour)
{
if (availableColours[colour])
{
break;
}
}
verticesColours[u] = colour;
for (const auto& neighbour : adjacency_list[u])
{
if (verticesColours[neighbour] != -1)
{
availableColours[verticesColours[neighbour]] = true;
}
}
}
return verticesColours;
}
Vector< int > Graph::lfColoring()
{
Vector< int > verticesColours(number_of_vertices, -1);
Vector< bool > availableColours(number_of_vertices, true);
Vector< std::pair< int, int > > verticesWihNumber;
verticesWihNumber.reserve(number_of_vertices);
for (int u = 0; u < number_of_vertices; ++u)
{
verticesWihNumber.push_back({ u, adjacency_list[u].size() });
}
std::sort(verticesWihNumber.begin(), verticesWihNumber.end(), [](
const auto& a,
const auto& b)
{
if (a.second != b.second)
return a.second > b.second;
else
return a.first < b.first;
}
);
for (const auto& [u, _] : verticesWihNumber)
{
std::fill(availableColours.begin(), availableColours.end(), true);
for (const auto& neighbour : adjacency_list[u])
{
if (verticesColours[neighbour] != -1)
{
availableColours[verticesColours[neighbour]] = false;
}
}
int colour = 1;
for (; colour < number_of_vertices; ++colour)
{
if (availableColours[colour])
{
break;
}
}
verticesColours[u] = colour;
}
return verticesColours;
}
int Graph::countComplementsEdges()
{
int complementEdges;
int maxEdges = number_of_vertices * (number_of_vertices - 1) / 2;
int currentEdges = 0;
for (const auto& adjacency : adjacency_list)
{
currentEdges += static_cast<int>(adjacency.size());
}
currentEdges /= 2;
complementEdges = maxEdges - currentEdges;
return complementEdges;
}
void Graph::depthSearch(int v, Vector< bool >& visited)
{
visited[v] = true;
for (int u : adjacency_list[v])
{
if (!visited[u])
{
depthSearch(u, visited);
}
}
}
void readInput(Vector< Graph >& graphs)
{
const int adjustIndexToArray = 1;
int numberOfGraphs = 0;
std::cin >> numberOfGraphs;
std::cin.ignore();
for (int i = 0; i < numberOfGraphs; ++i)
{
int numberOfVertices = 0;
std::cin >> numberOfVertices;
std::cin.ignore();
Graph g(numberOfVertices);
for (int j = 0; j < numberOfVertices; j++)
{
String line;
readLine(std::cin, line);
std::stringstream ss(line.c_str());
int number;
ss >> number;
Adjacency adj;
while (ss >> number)
{
adj.push_back(number - adjustIndexToArray);
}
g.addEdge(j, adj);
}
graphs.push_back(g);
}
}
int main()
{
Vector< Graph > graphs;
readInput(graphs);
for (auto& g : graphs)
{
Vector< int > degrees = g.degreeSequence();
std::sort(degrees.begin(), degrees.end(), std::greater<>());
for (const int d : degrees)
{
std::cout << d << "";
}
std::cout << '\n';
int components = g.countComponents();
std::cout << components;
std::cout << '\n';
char bipartite = g.isBipartite();
std::cout << bipartite;
std::cout << '\n';
Vector< int > eccentricities = g.eccentricity();
for (const int e : eccentricities)
{
std::cout << e << "";
}
std::cout << '\n';
std::cout << '?';
std::cout << '\n';
Vector< int > greedyColours = g.greedyColoring();
for (const int gc : greedyColours)
{
std::cout << gc << "";
}
std::cout << '\n';
Vector< int > lfColours = g.lfColoring();
for (const int lf : lfColours)
{
std::cout << lf << "";
}
std::cout << '\n';
std::cout << '?';
std::cout << '\n';
std::cout << '?';
std::cout << '\n';
int complementEdges = g.countComplementsEdges();
std::cout << complementEdges;
std::cout << '\n';
}
return 0;
}
Editor is loading...
Leave a Comment