int main(){ int i,n,m,max,total; int w[15000][3]; int pair[1000][2]; while(scanf("%d%d",&n,&m)!=EOF){ total=0; max=0; for(i=0;i<m;++i) scanf("%d%d%d",&w[i][1],&w[i][2],&w[i][0]); for(i=0;i<=n;i++){ parent[i]=i; height[i]=1; } qsort(w, m, sizeof(int)*3, cmp); for(i=0;i<m;++i) if(findSet(w[i][1])!=findSet(w[i][2])){ unionSet(findSet(w[i][1]),findSet(w[i][2])); pair[total][0]=w[i][1]; pair[total][1]=w[i][2]; total++; if(w[i][0]>max) max=w[i][0]; } printf("%d\n%d\n",max,total); for(i=0;i<total;i++) printf("%d %d\n",pair[i][0],pair[i][1]); } return 0; }
int unionSet(int i, int j){ if(isSameSet(i,j)) return psize[findSet(j)]; if(psize[findSet(j)] < psize[findSet(i)]) return unionSet(j, i); psize[findSet(j)] += psize[findSet(i)]; pset[findSet(i)] = findSet(j); return psize[findSet(j)]; }
int kruskal(Edge* e, int n_edge, int n_v) { int cost, i; qsort((void*)e, n_edge, sizeof(e[0]), cmp); cost = 0; for(i = 0;i < n_edge; i++) { if(unionSet(e[i].u, e[i].v)) cost += e[i].w; } return cost; }
// The main function that prints LCAs. u is root's data. // m is size of q[] void lcaWalk(int u, struct Query q[], int m, struct subset subsets[]) { // Make Sets makeSet(subsets, u); // Initially, each node's ancestor is the node // itself. subsets[findSet(subsets, u)].ancestor = u; int child = subsets[u].child; // This while loop doesn't run for more than 2 times // as there can be at max. two children of a node while (child != 0) { lcaWalk(child, q, m, subsets); unionSet (subsets, u, child); subsets[findSet(subsets, u)].ancestor = u; child = subsets[child].sibling; } subsets[u].color = BLACK; for (int i = 0; i < m; i++) { if (q[i].L == u) { if (subsets[q[i].R].color == BLACK) { printf("LCA(%d %d) -> %d\n", q[i].L, q[i].R, subsets[findSet(subsets,q[i].R)].ancestor); } } else if (q[i].R == u) { if (subsets[q[i].L].color == BLACK) { printf("LCA(%d %d) -> %d\n", q[i].L, q[i].R, subsets[findSet(subsets,q[i].L)].ancestor); } } } return; }
int kruskal(Edge* e, int n_edge, int n_v) { int max, i; makeSet(n_v); qsort((void*)e, n_edge, sizeof(e[0]), cmp); max = 0; for(i = 0;i < n_edge; i++) { if(findSet(e[i].u) != findSet(e[i].v)) { max = e[i].w > max ? e[i].w : max; unionSet(e[i].u, e[i].v); } } return max; }
int main() { char w; int n_edge, n_v, res, q, a, b; while(scanf("%d", &n_v) != EOF) { n_edge = build_graph(n_v); makeSet(n_v); scanf("%d", &q); while(q--) { scanf("%d %d", &a, &b); unionSet(a, b); } res = kruskal(e, n_edge, n_v); printf("%d\n", res); } return 0; }
//--------------------------------------------------------second solution--------------------------------------------------------------- //@desc: union-set idea //@time complexity: O(m*n) //@space complexity: O(m*n) int numIslands(vector<vector<char>>& grid) { int ret = 0; if (grid.size() <= 0) { return ret; } vector<int> unionSet(grid.size() * grid[0].size(), INT_MAX); int row = grid.size(); int col = grid[0].size(); for (int y = 0; y < row; y++) { for (int x = 0; x < col; x++) { if (grid[y][x] == '1') { int pos = y * col + x; unionSet[pos] = -1; if (x>= 1 && grid[y][x-1] == '1') { int pos2 = y * col + x - 1; unon(pos, pos2, unionSet); } if (y >= 1 && grid[y-1][x] == '1') { int pos2 = (y-1) * col + x; unon(pos, pos2, unionSet); } } } } for (int y = 0; y < row; y++) { for (int x = 0; x < col; x++) { if (unionSet[y * col + x] == -1) { ret++; } } } return ret; }
int countComponents(int n, vector<pair<int, int> >& edges) { root = vector<int>(n, -1); int size = edges.size(); //int count = n; for(int i = 0; i < size; ++i) { int u = edges[i].first; int v = edges[i].second; int uroot = findRoot(u); int vroot = findRoot(v); if(uroot != vroot) { //--count; unionSet(uroot, u, vroot, v); } } int count = 0; for (int i = 0; i < n; i++) { if (findRoot(i) == i) count++; } //return count; return count; }
/** * Create and print out a row. * @param isLast if this is the last row */ void makeRow(bool isLast) { uint startingSetNum = 1; // Make sure each cell is in a set and save the previousRow for (uint r = 0; r < width; r++) { previousRow[r] = row[r]; if ((row[r] & DOWN)) row[r] = UP; else { // Find the lowest set number that isn't already taken bool foundNext = false; while (!foundNext) { bool found = false; for (uint r = 0; r < width; r++) { if (set[r] == startingSetNum) { startingSetNum++; found = true; break; } } if (!found) foundNext = true; } set[r] = startingSetNum; row[r] = EMPTY; } } // Randomly fill in the cells with connections down or to the left for (uint i = 0; i < width; i++) { if (rand() % 2 == 1) { if (i > 0 && set[i] != set[i - 1]) { row[i] |= LEFT; row[i - 1] |= RIGHT; unionSet(set[i], set[i - 1]); } } if ((rand() % 2 == 1) && !isLast) { row[i] |= DOWN; } } // If there are any sets that don't move down in this row, // make them go down. if (!isLast) { for (uint r = 0; r < width; r++) { if (row[r] & DOWN) continue; uint mset = set[r]; bool goDown = true; for (uint i = 0; i < width; i++) { if (set[i] == mset && row[i] & DOWN) { goDown = false; break; } } if (goDown) { row[r] |= DOWN; } } } // last row, merge all sets so there is a path from any point // to any other point (sense they are all in one set) if (isLast) { for (uint r = 0; r < width - 1; r++) { if (set[r] == set[r + 1]) continue; row[r] |= RIGHT; row[r + 1] |= LEFT; unionSet(set[r + 1], set[r]); } } }
Join* MultiJoin::splitSubset(const JBBSubset & leftSet, const JBBSubset & rightSet, NABoolean reUseMJ) const { // At this point assert that none of the subsets has a group by member CMPASSERT ( (jbbSubset_.getGB() == NULL_CA_ID) && (leftSet.getGB() == NULL_CA_ID) && (rightSet.getGB() == NULL_CA_ID) ); #ifndef NDEBUG // assert that left + right == subSet_ // and left intersect right = phi CANodeIdSet unionSet(leftSet.getJBBCs()); CANodeIdSet intersectSet(leftSet.getJBBCs()); unionSet += rightSet.getJBBCs(); intersectSet.intersectSet(rightSet.getJBBCs()); CMPASSERT ( (unionSet == jbbSubset_.getJBBCs()) && (intersectSet.entries() == 0 )); #endif // Note: Joins including left, semi, anti semi are only created when // a single jbbc connected via one of them is split as a single right // child. InnerNonSemi joins can be created for any split i.e. any // number of jbbcs on the left and the right of the join, but special // joins (i.e. left, semi and anti semi joins) are only created when // there is a single right child i.e. the rightSet contains only one // jbbc that is connected via a special join. This is enforced as follows // // * The leftSet should be legal: This means that for every jbbc in the // leftSet any predecessor jbbcs should be present in the leftSet. // * The rightSet is either a single jbbc or if the rightSet has more // than one jbbc then it should be legal, note that a jbbc connected // via a special join is not a legal set by itself but we allow // creation of special joins assuming the predecessors are present // in the leftSet. // // An implicit assumption here is that 'this' MultiJoin is legal, which // is fair since apart from the top level multijoin, rest of the multijoins // are produced by splitting the top level multijoin. This method should // not produce illegal multijoins, since we check both leftSet and rightSet // for legality. Only time we don't check for legality is when the rightChild // is a single jbbc, and a single jbbc does not result in a multijoin. if(!leftSet.legal()) return NULL; if((rightSet.getJBBCs().entries() > 1) && (!rightSet.legal())) return NULL; // everything here goes to statement heap CollHeap* outHeap = CmpCommon::statementHeap(); RelExpr* child0 = generateSubsetExpr(leftSet, reUseMJ); RelExpr* child1 = generateSubsetExpr(rightSet, reUseMJ); // Flag to remember to pass on the derivedFromRoutineJoin flag if needed. NABoolean derivedFromRoutineJoin(FALSE); // now form a JoinExpr with these left and right children. Join * result = NULL; // if the rightSet is a single jbbc, then it could be connected via // a special join. In such a case we have to create the appropriate // join operator if(rightSet.getJBBCs().entries() == 1){ JBBC * rightChild = rightSet.getJBBCs().getFirst().getNodeAnalysis() ->getJBBC(); Join * rightChildParentJoin = rightChild->getOriginalParentJoin(); // If rightChildParentJoin is NULL, then the child is the left // child of the left most join and is considered to be connected // via a InnerNonSemi join. if(rightChildParentJoin) { if(rightChildParentJoin->derivedFromRoutineJoin()) derivedFromRoutineJoin = TRUE; if(rightChildParentJoin->isSemiJoin()) result = new (outHeap) Join(child0, child1, REL_SEMIJOIN, NULL); if(rightChildParentJoin->isAntiSemiJoin()) result = new (outHeap) Join(child0, child1, REL_ANTI_SEMIJOIN, NULL); if(rightChildParentJoin->isLeftJoin()) { // left joins can have filter preds, i.e. predicates that // are applied as filters after applying the join predicate. // We need to set them here. result = new (outHeap) Join(child0, child1, REL_LEFT_JOIN, NULL); result->setSelectionPredicates(rightChild->getLeftJoinFilterPreds()); } if(rightChildParentJoin->isRoutineJoin()) { derivedFromRoutineJoin = TRUE; result = new (outHeap) Join(child0, child1, REL_ROUTINE_JOIN, NULL); ValueIdSet routineJoinFilterPreds = rightChild->getRoutineJoinFilterPreds(); ValueIdSet predsToAddToRoutineJoin; // add covered filter preds for (ValueId filterPred= routineJoinFilterPreds.init(); routineJoinFilterPreds.next(filterPred); routineJoinFilterPreds.advance(filterPred) ) { if(jbbSubset_.coversExpr(filterPred)) predsToAddToRoutineJoin += filterPred; } result->setSelectionPredicates(predsToAddToRoutineJoin); } if(result) { // set the join predicate for special joins, note predicates // for regular InnerNonSemi joins are set as selection predicates // in the join relexpr. result->setJoinPred(rightChild->getPredsWithPredecessors()); result->nullInstantiatedOutput().insert(rightChild-> nullInstantiatedOutput()); } } } // The join to be created is a regular InnerNonSemi join if (!result) result = new (outHeap) Join(child0, child1, REL_JOIN, NULL); // Make sure we carry the derivedFromRoutineJoin flag with us if (derivedFromRoutineJoin) result->setDerivedFromRoutineJoin(); // Share my groupAttr with result result->setGroupAttr(getGroupAttr()); // get inner join predicates ValueIdSet selPreds = rightSet.joinPredsWithOther(leftSet); // get left join filter preds if any selPreds += result->getSelectionPredicates(); result->setSelectionPredicates(selPreds); result->findEquiJoinPredicates(); // May be I could save a little if i pushdown only to the child(ren) // that are not already JBBCs, i.e. multijoins result->pushdownCoveredExpr (result->getGroupAttr()->getCharacteristicOutputs(), result->getGroupAttr()->getCharacteristicInputs(), result->selectionPred()); // We used CutOp as children, to avoid pushing predicates to JBBCs. // Now put the actual expression back in case the child is a JBBCs if(leftSet.getJBBCs().entries() == 1) result->setChild(0, getJBBCRelExpr(leftSet.getJBBCs().getFirst())); // We used CutOp as children, to avoid pushing predicates to JBBCs. // Now put the actual expression back in case the child is a JBBCs if(rightSet.getJBBCs().entries() == 1) result->setChild(1, getJBBCRelExpr(rightSet.getJBBCs().getFirst())); // Temp fixup. We need to take the selectionPred out of MultiJoin // for now to prevent that pushed expr from being there. selectionPred // is not being used now in MultiJoin xxx. if (leftSet.getJBBCs().entries() > 1) result->child(0)->selectionPred().clear(); if (rightSet.getJBBCs().entries() > 1) result->child(1)->selectionPred().clear(); return result; }