#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define pb push_back #define mp make_pair #define pii pair #define vi vector #define vpii vector #define SZ(x) ((int)(x.size())) #define fi first #define se second #define FOR(i,n) for(int (i)=0;(i)<(n);++(i)) #define FORI(i,n) for(int (i)=1;(i)<=(n);++(i)) #define IN(x,y) ((y).find((x))!=(y).end()) #define ALL(t) t.begin(),t.end() #define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++) #define REP(i,a,b) for(int (i)=(a);(i)<=(b);++i) #define REPD(i,a,b) for(int (i)=(a); (i)>=(b);--i) #define REMAX(a,b) (a)=max((a),(b)); #define REMIN(a,b) (a)=min((a),(b)); #define DBG cerr << "debug here" << endl; #define DBGV(vari) cerr << #vari<< " = "<< (vari) <::iterator ptr[M]; Edge edges[M]; /** * Union FInd */ int member[N]; int uf_rank[N]; void uf_init(int n) { FOR(i, n) member[i] = i; FOR(i, n) uf_rank[i] = 1; } int uf_find(int v) { if(member[v] == v) return v; int fv = uf_find(member[v]); member[v] = fv; return fv; } bool uf_union(int a, int b) { int fa = uf_find(a); int fb = uf_find(b); if (fa == fb) return false; if (uf_rank[fa] > uf_rank[fb]) { member[fb] = fa; uf_rank[fa] += uf_rank[fb]; } else { member[fa] = fb; uf_rank[fb] += uf_rank[fa]; } return true; } bool visited[N]; void visit_g(int v) { visited[v] = 1; for (int u : g[v]) { if (visited[u]) continue; visit_g(u); } } /** * Main * */ int main() { int n, m, q; scanf("%d %d %d", &n, &m, &q); assert(n >= 2 && n <= N); assert(m >= 1 && m <= M); assert(q >= 1 && q <= Q); vector tmp_edges; FOR(i, n) FOR(j, n) edge_id[i][j] = -1; FOR(i, m) { int v, u, w; scanf("%d %d %d", &v, &u, &w); assert(v >= 1 && v <= n); assert(u >= 1 && u <= n); --v, --u; if (v > u) swap(v, u); g[v].pb(u); g[u].pb(v); assert(edge_id[v][u] == -1); edge_id[v][u] = i; marked[i] = 0; tmp_edges.pb(Edge(i, v, u, w)); edges[i] = Edge(i, v, u, w); } visit_g(0); FOR(i, n) assert(visited[i]); sort(ALL(tmp_edges), mycmp); uf_init(n); list candidates; ll res = 0; for (int i = 0; i < tmp_edges.size() && candidates.size() < n-1; ++i) { Edge e = tmp_edges[i]; if (uf_union(e.v, e.u)) { res += e.w; candidates.pb(mp(e.id, e.w)); } } int cnt_qtype3 = 0; bool need_recomputing = false; while (q--) { int qtype; scanf("%d", &qtype); if (qtype == 1 || qtype == 2) { int v, u; scanf("%d %d", &v, &u); assert(v >= 1 && v <= n); assert(u >= 1 && u <= n); --v, --u; if (v > u) swap(v, u); int eid = edge_id[v][u]; assert(eid != -1); if (qtype == 1) { if (!marked[eid]) { candidates.push_front(mp(eid, 0)); ptr[eid] = candidates.begin(); marked[eid] = 1; need_recomputing = true; } } else if (qtype == 2) { if (marked[eid]) { candidates.erase(ptr[eid]); marked[eid] = 0; need_recomputing = true; } } } else if (qtype == 3) { cnt_qtype3++; if (need_recomputing) { res = 0; int cnt = 0; uf_init(n); for (auto it = candidates.begin(); it != candidates.end() && cnt < n-1; ++it) { int eid = it->fi; int v = edges[eid].v; int u = edges[eid].u; int w = it->se; if (uf_union(v, u)) { res += w; ++cnt; } } need_recomputing = false; } printf("%lld\n", res); } else assert(false); } return 0; }