Untitled

 avatar
unknown
c_cpp
9 months ago
14 kB
3
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 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