Cod sursa(job #2955299)

Utilizator YosifIosif Andrei Stefan Yosif Data 16 decembrie 2022 18:33:45
Problema Lazy Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 9.11 kb
#include <bits/stdc++.h> 
using namespace std;

ifstream fin("lazy.in");
ofstream fout("lazy.out");

class num
{
private:

    int sign;
    string val;

public:

    num()
    {
        sign = 1;
        val = "0";
    }

    num(string s)
    {
        int l = 0, r = s.length() - 1;

        if (s[0] == '-')
            sign = -1, s.erase(s.begin()), r--;
        else
            sign = 1;

        while (l < r)
        {
            swap(s[l], s[r]);
            l++, r--;
        }

        val = s;
    }

    num(int n)
    {
        if (n == 0)
        {
            sign = 1;
            val = "0";
            return;
        }

        if (n < 0)
            sign = -1, n *= -1;
        else
            sign = 1;

        while (n)
        {
            val += char(n % 10 + '0');
            n /= 10;
        }
    }

    operator string () const
    {
        string out = "";

        if (sign == -1)
            out += '-';

        int i = val.length() - 1;

        while (i >= 0)
            out += val[i--];

        return out;
    }

    num operator - () const
    {
        num rez = *this;
        if (rez.val != "0")
            rez.sign *= -1;
        return rez;
    }

    friend bool operator < (const num& a, const num& b)
    {
        if (a.sign == -1 && b.sign == 1)
            return 1;
        else if (a.sign == 1 && b.sign == -1)
            return 0;

        if (a.sign == -1 && b.sign == -1)
        {
            if (a.val.length() < b.val.length())
                return 0;
            else if (a.val.length() > b.val.length())
                return 1;

            int i = a.val.length() - 1;

            while (i >= 0)
            {
                if (a.val[i] < b.val[i])
                    return 0;
                else if (a.val[i] > b.val[i])
                    return 1;

                i--;
            }

            return 0;
        }

        if (a.val.length() < b.val.length())
            return 1;
        else if (a.val.length() > b.val.length())
            return 0;

        int i = a.val.length() - 1;

        while (i >= 0)
        {
            if (a.val[i] < b.val[i])
                return 1;
            else if (a.val[i] > b.val[i])
                return 0;

            i--;
        }

        return 0;
    }

    friend bool operator == (const num& a, const num& b)
    {
        if (a.val.length() != b.val.length() || a.sign != b.sign)
            return 0;

        int i = 0;

        while (i < a.val.length())
        {
            if (a.val[i] != b.val[i])
                return 0;
            i++;
        }

        return 1;
    }

    num operator + (const num& n) const
    {
        if (sign == -1 && n.sign == -1)
            return -((*this).abs() + n.abs());

        if (sign == -1 && n.sign == 1)
        {
            if ((*this).abs() < n)
                return n - (*this).abs();
            else
                return -((*this).abs() - n);
        }

        if (sign == 1 && n.sign == -1)
            return (*this) - n.abs();

        num rez;
        rez.val = "";
        rez.sign = 1;

        int t = 0;

        int i = 0, mini = min(n.val.length(), val.length());

        while (i < mini)
        {
            t += n.val[i] + val[i] - '0' - '0';
            rez.val += char(t % 10 + '0');
            t /= 10;
            i++;
        }

        while (i < n.val.length())
        {
            t += n.val[i] - '0';
            rez.val += char(t % 10 + '0');
            t /= 10;
            i++;
        }

        while (i < val.length())
        {
            t += val[i] - '0';
            rez.val += char(t % 10 + '0');
            t /= 10;
            i++;
        }

        while (t)
            rez.val += char(t % 10 + '0'), t /= 10;

        while (rez.val.length() > 1 && rez.val.back() == '0')
            rez.val.pop_back();

        return rez;
    }

    num operator - (const num& n) const
    {
        if (sign == -1 && n.sign == 1)
            return -((*this).abs() + n.abs());

        if (n.sign == -1)
            return (*this) + n.abs();

        if ((*this) < n)
            return -(n - (*this));

        num rez, aux = *this;
        rez.val = "";
        rez.sign = 1;

        int i = 0;

        while (i < aux.val.length() && i < n.val.length())
        {
            if (aux.val[i] >= n.val[i])
            {
                rez.val += char(aux.val[i] - n.val[i] + '0');
                i++;
                continue;
            }

            int j = i + 1;

            while (aux.val[j] == '0')
                aux.val[j++] = '9';
            aux.val[j]--;

            rez.val += char(10 + aux.val[i] - n.val[i] + '0');

            if (j + 1 == aux.val.length() && aux.val[j] == '0')
                aux.val.pop_back();

            i++;
        }

        while (i < aux.val.length())
            rez.val += aux.val[i++];

        while (rez.val.length() > 1 && rez.val.back() == '0')
            rez.val.pop_back();

        return rez;
    }

    num operator * (const num& n) const
    {
        num rez;
        rez.val = "";
        rez.sign = sign * n.sign;

        vector <int> a(val.length() + n.val.length() - 1);

        for (int i = 0; i < val.length(); i++)
            for (int j = 0; j < n.val.length(); j++)
                a[i + j] += int(1) * (val[i] - '0') * (n.val[j] - '0');

        int t = 0;

        for (int i = 0; i < a.size(); i++)
        {
            t += a[i];
            rez.val += char(t % 10 + '0');
            t /= 10;
        }

        while (t)
            rez.val += char(t % 10 + '0'), t /= 10;

        while (rez.val.length() > 1 && rez.val.back() == '0')
            rez.val.pop_back();

        return rez;
    }

    num operator / (const num& aux) const
    {
        num c, rez, n = aux;
        n = n.abs();

        if ((*this).abs() < n)
            return 0;

        if (n.val == "0")
            throw;

        int i = val.length() - 1, cnt;

        while (c < n)
            c = c * 10 + (val[i--] - '0');

        cnt = 0;

        while (!(c < n))
            c = c - n, cnt++;

        rez = rez * 10 + cnt;

        while (i >= 0)
        {
            c = c * 10 + (val[i] - '0');
            cnt = 0;
            while (!(c < n))
                c = c - n, cnt++;
            rez = rez * 10 + cnt;
            i--;
        }

        rez.sign = sign * aux.sign;
        return rez;
    }

    num operator % (const num& aux) const
    {
        num c, n = aux;
        n = n.abs();

        if ((*this).abs() < n)
            return (*this).abs();

        if (n.val == "0")
            throw;

        int i = val.length() - 1, cnt;

        while (c < n)
            c = c * 10 + (val[i--] - '0');

        cnt = 0;

        while (!(c < n))
            c = c - n, cnt++;

        while (i >= 0)
        {
            c = c * 10 + (val[i] - '0');
            cnt = 0;
            while (!(c < n))
                c = c - n, cnt++;
            i--;
        }

        return c;
    }

    friend istream& operator >> (istream& in, num& n)
    {
        in >> n.val;

        if (n.val[0] == '-')
            n.sign = -1, n.val.erase(n.val.begin());
        else
            n.sign = 1;

        int l = 0, r = n.val.length() - 1;

        while (l < r)
        {
            swap(n.val[l], n.val[r]);
            l++, r--;
        }

        while (n.val.length() > 1 && n.val.back() == '0')
            n.val.pop_back();

        return in;
    }

    friend ostream& operator << (ostream& out, const num& n)
    {
        if (n.sign == -1 && n.val != "0")
            out << '-';

        int i = n.val.length() - 1;

        while (i >= 0)
            out << n.val[i--];

        return out;
    }

    num abs() const
    {
        num New = *this;
        New.sign = 1;
        return New;
    }
};

class sets {
private:

    int t[200001];

public:

    sets()
    {
        for (int i = 1; i <= 200000; i++)
            t[i] = i;
    }

    int root(int x)
    {
        if (t[x] == x)
            return x;
        else
            return t[x] = root(t[x]);
    }

    void unit(int x, int y)
    {
        t[root(x)] = root(y);
    }

    bool connected(int x, int y)
    {
        return root(x) == root(y);
    }
};

int n, m;
sets S;

struct edge {
    int x, y, poz;
    num c1, c2;

    bool operator < (edge aux)
    {
        if (c1 < aux.c1)
            return true;
        else if (c1 == aux.c1 && !(c1 * c2 < aux.c1 * aux.c2))
            return true;
        return false;
    }

}v[200001];

int main()
{
    fin >> n >> m;

    for (int i = 1; i <= m; i++)
        fin >> v[i].x >> v[i].y >> v[i].c1 >> v[i].c2, v[i].poz = i;

    sort(v + 1, v + m + 1);

    for (int i = 1; i <= m; i++)
        if (!S.connected(v[i].x, v[i].y))
            fout << v[i].poz << '\n', S.unit(v[i].x, v[i].y);

    return 0;
}