Cod sursa(job #998788)

Utilizator manutrutaEmanuel Truta manutruta Data 18 septembrie 2013 00:01:28
Problema Sate Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3 kb
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdio>
#include <bitset>
using namespace std;

FILE* f = fopen("online.in", "r");
FILE *g = fopen("online.out", "w");

#define MAXN 210
#define MAXM 1010


class edge {
public:
    edge() {};
    edge(int _x, int _y, int _c) :x(_x), y(_y), c(_c) {};
    int x, y, c;

    static bool compare(const edge& a, const edge& b) {
        return a.c < b.c;
    }
};

class disjoint {
public:
    disjoint(){};

    void init ()
    {
        for (int i = 0; i < MAXN; ++i) {
            parent[i] = i;
            rank[i] = 1;
        }
    }

    bool united(int x, int y)
    {
        return find(x) == find(y);
    }

    void unite(int x, int y)
    {
        x = find(x), y = find(y);

        if (rank[x] > rank[y]) {
            parent[y] = x;
        } else {
            parent[x] = y;
        }

        if (rank[x] == rank[y]) {
            rank[y]++;
        }
    }

private:
    int find (int x) {
        int xx = x;
        while (parent[xx] != xx) {
            xx = parent[xx];
        }

        while (x != parent[x]) {
            int t = parent[x];
            parent[x] = xx;
            x = t;
        }
        return xx;
    }

private:
    int parent[MAXN];
    int rank[MAXN];
};

typedef vector<edge>::iterator iter;
typedef vector<pair<int, int> >::iterator g_iter;

disjoint d;

int n, m;

vector<edge> edges, apm;

void insert(edge e)
{
    if (e.c >= (edges.end() - 1)->c) {
        edges.push_back(e);
        return;
    }

    int beg = 0, end = edges.size(), mdl, last = 0;
    while(beg <= end){
        mdl = beg + ((end - beg)>>1);
        if (edges[mdl].c >= e.c){
            last = mdl, end = mdl - 1;
        } else {
            beg = mdl + 1;
        }
    }

    edges.insert(edges.begin() + last, e);
}

int main()
{
    fscanf (f, "%d %d\n", &n, &m);

    edges.resize(m);
    for (int i = 0; i < m; ++i) {
        fscanf (f, "%d %d %d\n", &edges[i].x, &edges[i].y, &edges[i].c);
    }

    d.init();
    sort(edges.begin(), edges.end(), edge::compare);

    int cost = 0;
    for (iter it = edges.begin(); it != edges.end(); ++it) {
        if (!d.united(it->x, it->y)) {
            d.unite(it->x, it->y);
            cost += it->c;
            apm.push_back(*it);
        }
    }

    fprintf (g, "%d\n", cost);

    int k;
    fscanf (f, "%d\n", &k);
    for (int i = 0, x, y, c; i < k; ++i) {
        fscanf (f, "%d %d %d\n", &x, &y, &c);

        edges = apm;
        edge e(x, y, c);
        insert(e);

        apm.clear();

        d.init();

        int cost = 0;
        for (iter it = edges.begin(); it != edges.end(); ++it) {
            if (!d.united(it->x, it->y)) {
                d.unite(it->x, it->y);
                cost += it->c;
                apm.push_back(*it);
            }
        }

        fprintf (g, "%d\n", cost);
    }

    fclose(f);
    fclose(g);
    return 0;
}