예제 #1
0
파일: POJ1861.c 프로젝트: aacczury/ACM
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;
}
예제 #2
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)];
}
예제 #3
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
파일: 200.cpp 프로젝트: aaahexing/cheer
//--------------------------------------------------------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;
 }
예제 #9
0
/**
 * 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]);
        }
    }
}
예제 #10
0
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;
}