Да, идеи отличные, в этом то и дело. Кажется вот что-то не то.
Не должна эта задача решаться так отлично от других из того же раздела
задач про минимальные остовы.
У меня появилась идейка решения, и я ее реализовал на С++, для test caseов
из условия задачи ответы верные, да и не нашел пока тестов на которых решение валится.
Но системное тестирование решение не прошло.
Тут нужен какой-то тест на котором он валится, если не найду такой, попробую реализовать
идею 
sup.
Идея такова:
1. Сгруппируем ребра по весам (Т. к. диапазон значений весов небольшой можно создать
массив списков, ну, это я отвлекся к реализации).
2. Представим граф без его ребер, очевидно что каждая вершина - компонента связности.
3. Добавим группу ребер с максимальным весом, после чего некоторые компоненты связности объединятся.
4. Посчитаем сумму мощностей каждой, возникшей в результате шага 3, компоненты связности (очевидно, что каждая из них - кандидат).
5. Удалим добавленную группу ребер и перейдем к шагу 3, если ребер не осталось переходим к шагу 6.
6. Конец алгоритма.
Я использовал Стуркутуры Данных UFDS для определения новых возникших компонент связности.
Здесь представлен код:
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <cmath>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cassert>
#include <cstring>
#include <climits>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define INF INT_MAX-1
#define SQR(x) ((x)*(x))
using namespace std;
#define vertex_sz_MAX   5001
#define edge_w_MAX              100001
/* ufds */
namespace {
        int parent[vertex_sz_MAX];
        int size[vertex_sz_MAX];
        void init_set() {
                for (int i = 0; i < vertex_sz_MAX; ++i) {
                        parent[i] = i;
                        size[i] = 1;
                }
        }
        int find_set(int x) {
                return x == parent[x] ? x : parent[x] = find_set(parent[x]);
        }
        /* keeps track about newly formed components */
        void join_set(int x, int y, set<int> & new_comp) {
                x = find_set(x);
                y = find_set(y);
                if (x == y)
                        return;
                if (size[x] > size[y]) {
                        parent[y] = x;
                        size[x] += size[y]; new_comp.insert(x);
                        size[y] = 0; new_comp.erase(y);
                } else {
                        parent[x] = y;
                        size[y] += size[x]; new_comp.insert(y);
                        size[x] = 0; new_comp.erase(x);
                }
        }
}
int vertex_sz, edges_sz, w_max;
list<pair<int, int> > edges[ edge_w_MAX ];
int solve() {
        init_set();
        set<int> new_comp;
        int count = 0;
        for (int w = w_max; w >= 1; --w) {
                new_comp.clear();
                /* add edges with same weights */
                for (list<pair<int, int> >::iterator it = edges[w].begin(); it != edges[w].end(); ++it) {
                        join_set(it->first, it->second, new_comp);
                }
                for (set<int>::iterator it = new_comp.begin(); it != new_comp.end(); ++it) {
                        count += size[*it];
                }
        }
        return count;
}
int main() {
        int test_n, x, y, w;
        cin >> test_n;
        while (test_n--) {
                /* prepare stage */
                w_max = 0;
                for (int i = 0; i < edge_w_MAX; ++i)
                        edges[i].clear();
                /* input stage */
                cin >> vertex_sz >> edges_sz;
                while (edges_sz--) {
                        cin >> x >> y >> w;
                        w_max = max(w, w_max);
                        edges[w].push_back(make_pair(x, y));
                }
                /* solve and output */
                cout << solve() << endl;
        }
        return 0;
}
 
  -- 07.02.2015, 01:07 --Сложность алгоритма 

, где m - количесто ребер.