Пример #1
0
int main()
{
    Trie trie;
    DisjointSet djset;
    int degree[500001] = {0};
    string word1, word2;
    char w1[15], w2[15];
    int hash1, hash2;
    while (scanf("%s %s", w1, w2) != EOF) {
        hash1 = trie.addWord(w1);
        hash2 = trie.addWord(w2);
        degree[hash1]++;
        degree[hash2]++;
        djset.union_set(hash1, hash2);
    }
    int max_count = trie.max_count();
    int sum = 0;
    for (int i = 0; i < max_count; i++) {
        if (degree[i] & 1)
            sum++;
        if (sum > 2) {
            cout << "Impossible" << endl;
            return 0;
        }
    }

    for (int i = 0; i < max_count; i++) {
        if (djset.find_set(i) != djset.find_set(0)) {
            cout << "Impossible" << endl;
            return 0;
        }
    }
    cout << "Possible" << endl;
    return 0;
}
Пример #2
0
int main(int argc, char const *argv[]) {
    ios::sync_with_stdio(false);

    int t;
    DisjointSet *D;
    cin >> t;
    for (int cs = 0; cs < t; ++cs) {
        int n;
        double d;
        cin >> n >> d;
        VD x(n), y(n);
        for (int i = 0; i < n; ++i) {
            cin >> x[i] >> y[i];
        }
        D = new DisjointSet(n);
        for (int i = 0; i < n; ++i) {
            for (int j = i + 1; j < n; ++j) if ((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]) <= d * d) {
                    D->Union(i, j);
                }
        }
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            ans += D->parent[i] == i;
        }
        cout << "Case " << cs + 1 << ": " << ans << endl;
    }

    return 0;
}
Пример #3
0
int main(int argc, char const *argv[]) {
    ios::sync_with_stdio(false);

    int n, m;
    DisjointSet *D;
    while (cin >> n >> m && n != 0) {
        D = new DisjointSet(n);
        for (int i = 0; i < m; ++i) {
            int k;
            cin >> k;
            int a = -1, b;
            for (int j = 0; j < k; ++j) {
                cin >> b;
                if (a != -1) {
                    D->Union(a, b);
                }
                a = b;
            }
        }
        int suspect = 0;
        for (int i = 0; i < n; ++i) {
            suspect += D->Find(i) == D->Find(0);
        }
        cout << suspect << endl;
    }

    return 0;
}
Пример #4
0
int main(void) {
  std::cin.tie(0);
  int n, p, q;
  while(cin >> n && n) {
    cin >> p >> q;
    for(int i = 0; i < n; ++i)
      cin >> pts[i].first >> pts[i].second;
    vector<edge> es;
    for(int i = 0; i < n; ++i)
      for(int j = i+1; j < n; ++j)
        es.push_back(edge(i, j, dist(i, j)));
    sort(es.begin(), es.end());
    DisjointSet ds = DisjointSet(n);
    double ans = 0;
    ds.merge(p-1, q-1);
    ans += dist(p-1, q-1);
    for(size_t i = 0; i < es.size(); ++i) {
      if(ds.find(es[i].u) != ds.find(es[i].v)) {
        ds.merge(es[i].u, es[i].v);
        ans += es[i].c;
      }
    }
    printf("%.2lf\n", ans);
  }
  return 0;
}
Пример #5
0
int main(int argc, char const *argv[]) {
    ios::sync_with_stdio(false);

    int t;
    DisjointSet *D;
    cin >> t;
    for (int cs = 0; cs < t; ++cs) {
        int n, m;
        cin >> n >> m;
        D = new DisjointSet(n);
        for (auto& a : D->total) {
            cin >> a;
        }
        for (int i = 0; i < m; ++i) {
            int a, b;
            cin >> a >> b;
            D->Union(a, b);
        }
        string ans = "POSSIBLE";
        for (int i = 0; i < n; ++i) if (D->Find(i) == i && D->total[i] != 0) {
                ans = "IMPOSSIBLE";
            }
        cout << ans << endl;
    }

    return 0;
}
Пример #6
0
inline
int kruskal(Edge E[], const int size)
{
  static DisjointSet ds;
  int cnt = 0, sum = 0;
  REP(i, size){
    ds.make(i);
  }
Пример #7
0
 void solve() {
   step = 0;
   memset(dfn, -1, sizeof(int)*n);
   for (int i=0; i<n; i++) {
     if (dfn[i] == -1) DFS(i, i, -1);
   }
   djs.init(n);
   for (int i=0; i<n; i++) {
     if (low[i] < dfn[i]) djs.uni(i, par[i]);
   }
 }
Пример #8
0
int main() {
	DisjointSet djset;
	DisjointSet::NodePtr id[3];
	id[0] = djset.makeSet(0);
	id[1] = djset.makeSet(1);
	id[2] = djset.makeSet(2);

	djset.linkSets(id[0], id[1]);
	djset.linkSets(id[1], id[2]);

	DisjointSet::SetIdentifier t1 = djset.findSet(id[0]);
	DisjointSet::SetIdentifier t2 = djset.findSet(id[2]);
}
int main(int argc, char *argv[])
{
	if(argc < 2)
	{
		PrintHelp();
		return 1;
	}
	
	map<string, string> systems;
	DisjointSet links;
	
	ifstream in(argv[1]);
	string line;
	string current;
	while(getline(in, line))
	{
		// Skip blank lines.
		if(IsEmpty(line))
			continue;
		// If this line is not indented, it starts a new root object.
		if(line[0] > ' ')
			current.clear();
		
		if(Token(line, 0) == "system")
			current = Token(line, 1);
		else if(!current.empty() && Token(line, 0) == "link")
			links.Join(current, Token(line, 1));
		
		if(!current.empty())
		{
			systems[current] += line;
			systems[current] += '\n';
		}
	}
	
	vector<string> components;
	for(char **it = argv + 2; *it; ++it)
		components.push_back(*it);
	for(const pair<string, string> &it : systems)
	{
		bool match = components.empty();
		for(const string &component : components)
			match |= links.IsJoined(it.first, component);
		
		if(match)
			cout << it.second << endl;
	}
	return 0;
}
Пример #10
0
int main(int argc, char **argv)
{
	ifstream ifs;

	if (argc != 2)
	{
		cout << getlonglong("1 1 1 1") << endl;
		cout << getlonglong("1 0 1 0") << endl;
		return -1;
	}

	ifs.open(argv[1]);
	string str;
	ifs >> N >> M;
	getline(ifs, str);
	vl G = vl(N);
	DisjointSet ds = DisjointSet(N);

	for (int i = 0; i < N; ++i)
	{
		std::getline(ifs, str);
		G[i] = getlonglong(str);
	}

	sort(G.begin(), G.end());
	unionEquals(G, ds, CmpByMask(-1));

	/* find all nodes, which differ by single bit only */
	for (int i = 0; i < M; ++i)
	{
		long long mask = ~(1LL << i);
		sort(G.begin(), G.end(), CmpByMask(mask));
		unionEquals(G, ds, CmpByMask(mask));
	}
	/* find all nodes, which differ by two bits */
	for (int i = 0; i < M - 1; ++i)
	{
		for (int j = i + 1; j < M; ++j)
		{
			long long mask = ~((1LL << i) + (1LL << j));
			sort(G.begin(), G.end(), CmpByMask(mask));
			unionEquals(G, ds, CmpByMask(mask));
		}
	}
	/* output how many clusters do we have */
	cout << ds.getNumberOfComponent() << endl;

	return 0;
}
int main(int argc, char **argv) {
    if (argc != 2) {
        std::cout << "Usage: " << argv[0] << "||||| Should be: <MAXIMUM_NUMBER_OF_VERTICES>" << std::endl;
        return 0;
    }
    std::cout << "The maximus number of vertices is " << argv[1] << std::endl;
    
    
    // Try to translate MAXIMUM_NUMBER_OF_VERTICES
    // to size_t in order to determine the number of vertices.
    try {
        long num_of_nodes = std::stoi(argv[1]);
        if (num_of_nodes < 0) {
            std::cout << "Invalid argument for MAXIMUM_NUMBER_OF_NODES::Must be a positive integer!::TERMINATING PROGRAM\n";
            exit(1);
        }
        
        const size_t max_val = num_of_nodes;
        UndirectedGraph<size_t> testGraph;
        DisjointSet<size_t> testDS;
        
        size_t counter = 1;
        while (counter <= num_of_nodes) {
            testGraph.AddVertex(counter);
            testDS.AddNewNode(counter);
            ++counter;
        }

        srand(time(0)); //use current time as seed for random generator
        while (testDS.Size() > 1) {
            int i1 = rand() % max_val + 1;
            int i2 = rand() % max_val + 1;
            if (testGraph.AddEdge(i1, i2)) {
                testDS.Union(i1, i2);
            }
        }
        
//        testGraph.printGraph();
        testGraph.PrintGraphStats();
        
    } catch (std::invalid_argument) {
        std::cout << "Invalid argument for MAXIMUM_NUMBER_OF_NODES::Must be a positive integer::TERMINATING PROGRAM\n";
        exit(1);
    }
    
    
    return 0;
}
Пример #12
0
 void gao() {
   bcc.gao();
   for (const auto& i: bcc.bcc) {
     if (i.size() > 1) {
       for (const auto& j: i) {
         ds.setp(j.first, j.second);
       }
     }
   }
   for (const auto& i: bcc.bridge) {
     int a = ds.getp(i.first);
     int b = ds.getp(i.second);
     e[a].push_back(b);
     e[b].push_back(a);
   }
 }
Пример #13
0
void doAFind(DisjointSet set)
{
    cout << "Do a find on each number" << endl;
    for (int i = 0; i < 10; i++) {
        cout << "Find on "<< i << " = " << set.find(i) << endl;
    }
}
Пример #14
0
int kruskal(int N, vector<Edge> edges)
{
	int totalCost = 0;
	sort(edges.begin(), edges.end());
	DisjointSet dset = DisjointSet(N + 1);
	int source;
	int target;
	for (int i = 0; i < edges.size(); i++) {
		Edge e = edges[i];
		if (!dset.same(e.source, e.target)) {
			//MST.push_back(e);
			totalCost += e.cost;
			dset.unite(e.source, e.target);
		}
	}
	return totalCost;
}
long int kruskal(int m, vector<triple> &arestas){

	DisjointSet<int> *ds = new DisjointSet<int>(m);
	// vector<ii> result;
	long int t = 0;

	for(int i=0; i<m; i++)
		ds->make(i, 0);

	sort(arestas.begin(), arestas.end());

	int e = 0, i = 0;
	while(e < m-1){

		int u = ds->find(arestas[i].first);
		int v = ds->find(arestas[i].second);

		if(ds->find(u) != ds->find(v)){
			t += arestas[i].third;
			// result.push_back(ii(u, v));
			ds->join(u, v);
			e++;
		}

		i++;
	}

	return t;
}
int kruskal(int v)
{
    DisjointSet mst;
    int origen, destino, peso, total = 0;

    mst.initSet(v);
    sort(aristas.begin(), aristas.end());
    for(int i = 0; i < aristas.size(); i++){
        peso = aristas[i].first;
        origen = aristas[i].second.first;
        destino = aristas[i].second.second;
        if(!mst.isSameSet(origen, destino)){
            total += peso;
            mst.unionSet(origen, destino);
        }
    }
    return total;
}
Пример #17
0
int main(){
	int n;
	long q;
	scanf(" %d %ld", &n, &q);
	
	DisjointSet ds = DisjointSet(n);
	
	for(long i=0; i<q; ++i){
		int com, x, y;
		scanf(" %d %d %d", &com, &x, &y);
		
		if(com==0) ds.unite(x,y);	
		else if(com==1){
			if(ds.same(x,y)) printf("1\n");
			else printf("0\n");
		}
		
	}
}
Пример #18
0
void unionEquals(vl & G, DisjointSet &ds, CmpByMask cmp)
{
	for (uint i = 0; i < G.size() - 1; ++i)
	{
		/* if previous less than next */
		if (cmp(G[i], G[i + 1]))
		{
			continue;
		}

		/* two adjacent nodes are equal */
		/* check if they belong to different component and union them */
		/* BUG: keep index in G */
		if (ds.findSet(i) != ds.findSet(i + 1))
		{
			ds.unionNodes(i, i + 1);
		}
	}
}
void GraphController::kruskalRequest()
{
	viewer->unselectEdges();
	DisjointSet set;
	auto result = GraphAlgorithms::getKruskalMST(*graph, &set);

	if (result.empty())
	{
		viewer->showResult("No MST found.");
		return;
	}
	std::unordered_map<int, int> sums;
	std::vector<int> edgesIds;
	for (auto& edge: result)
	{
		int id = set.find(edge.getVertex1());
		auto it = sums.find(id);
		if (it != sums.end())
			it->second += edge.getWeight();
		else
		{
			sums[id] = edge.getWeight();
		}
		edgesIds.push_back(edge.getId());
	}
	std::vector<int> nodes;
	std::string st;
	for (auto& it:sums)
	{
		st += "(" + std::to_string(it.first) +") = " + std::to_string(it.second) + ", ";
		nodes.push_back(it.first);
	}
	st.erase(st.end() - 2, st.end());
	viewer->selectEdges(edgesIds, nodes);
	std::string s = "";
	if (nodes.size() > 1)
	{
		s = "s";
	}
	viewer->showResult((std::to_string(sums.size()) +" MST found with total weight"+s+":  " + st).c_str());
}
Пример #20
0
 ll MST (vector <pair <ll, PI>> *mst = NULL) {
     ll ret = 0;
     D = new DisjointSet(n);
     sort(all(edges));
     for (auto e : edges) if (D->Union(e.y.x, e.y.y)) {
             ret += e.x;
             if (mst) {
                 mst->push_back(e);
             }
         }
     return ret;
 }
/* Função principal. */
int main(void) {
	int n, m;

	/* Para cada caso de teste. */
	while(scanf("%d %d", &n, &m), n || m) {
		/* Limpando o meu vector. */
		edges.clear();
		ds.clear(n);

		/* Lendo cada aresta. */
		for (int i = 0; i < m; i++) {
			int v, u, weight;
			scanf("%d %d %d", &v, &u, &weight);
			edges.push_back(make_pair(weight, make_pair(v, u)));
		}

		/* Ordenando as arestas pelo peso. */
		sort(edges.begin(), edges.end());

		/* Kruskal, propriamente dito. */
		bool first = true;
		int economy = 0;

		for (int i = 0; i < m; i++) {
			/* Se os vértices têm representantes diferents, então eles estão em árvores diferentes e podem ser ligados por uma aresta sem gerar ciclo. */
			if (ds.ds_find(edges[i].second.first) != ds.ds_find(edges[i].second.second)) {
				ds.ds_union(edges[i].second.first, edges[i].second.second);
			}

			/* Senão, não. */
			else {
				economy += edges[i].first;
			}
		}
		printf("%d\n", economy);
	}


	return 0;
}
Пример #22
0
int main() {
	scanf("%d", &T);
	for (int t = 1; t <= T; ++t) {
		scanf("%d %d", &n, &m);
		scanf("%lf %lf %lf %lf %lf %lf %lf %lf", &a.F, &a.S, &b.F, &b.S, &c.F, &c.S, &d.F, &d.S);
		init(t1, n, p1, a, b);
		init(t2, m, p2, c, d);
		e.clear();
		for (int i = 1; i < n; ++i) {
			e.PB(MP(dis2(p1[i - 1], p1[i]), MP(i - 1, i)));
		}
		for (int i = 1; i < m; ++i) {
			e.PB(MP(dis2(p2[i - 1], p2[i]), MP(n + i - 1, n + i)));
		}
		for (int i = 0; i < n; ++i) {
			int p = ts(i, 0, m - 1);
			e.PB(MP(dis2(p1[i], p2[p]), MP(i, n + p)));
			if (p - 1 >= 0) {
				e.PB(MP(dis2(p1[i], p2[p - 1]), MP(i, n + p - 1)));
			}
			if (p + 1 < m) {
				e.PB(MP(dis2(p1[i], p2[p + 1]), MP(i, n + p + 1)));
			}
		}
		std::sort(e.begin(), e.end());
		ds.init(n + m);
		double mst = 0;
		FOR(i, e)
		{
			int u = (*i).S.F, v = (*i).S.S;
			if (ds.setp(u, v)) {
				mst += sqrt((*i).F);
			}
		}
		printf("Case #%d: %.3lf\n", t, mst);
	}
Пример #23
0
int main(int argc, char *argv[]) {
  DisjointSet ds;
  for (int set_number=0; set_number<DSET_SIZE; ++set_number) {
    ds.MakeSet(set_number);
  }
  srand(time(NULL));
  int unions = 0;
  int attempts = 0;
  while (ds.size() > 1) {
    // generate random couples and do Union operations, up to when there is
    // only a single set left.
    int x = rand() % DSET_SIZE;
    int y = rand() % DSET_SIZE;
    if (ds.Union(x,y)) {
      unions += 1;
    } else {
      attempts += 1;
    }
    //std::cout << ds.toDot() << std::endl;
  }
  std::cerr << "unions=" << unions << ", attempts=" << attempts << std::endl;
  std::cout << ds.toDot() << std::endl;
  return 0;
}
Пример #24
0
double Graph::MSTAlgo() {
  DisjointSet<Vertex>* A = new DisjointSet<Vertex>(n);
  double totalweight = 0;
  for(int i = 0; i < n; ++i){
	A->MakeSet(i, AdjacencyList[i]->getElem());
  }
  sortEdge();
  for(int i = 0; i < EdgeList.size(); ++i){
	if(A->FindSet(EdgeList[i]->vertex_i)->getKey() != A->FindSet(EdgeList[i]->vertex_j)->getKey()){
	  A->Union(*(A->FindSet(EdgeList[i]->vertex_i)), *(A->FindSet(EdgeList[i]->vertex_j)));
	  totalweight += EdgeList[i]->weight;
	  MST.push_back(EdgeList[i]);
	}
  }
  
  
  return totalweight;
}
Пример #25
0
void dfs(int r, int c, int n, DisjointSet& ds) {
  stack<rc> sta;
  sta.push(rc(r, c));
  while (!sta.empty()) {
    int r = sta.top().r;
    int c = sta.top().c;
    sta.pop();
    if (V[r][c]) continue;
    V[r][c] = 1;

    for (int i = 0; i < 4; i++) {
      int nr = r+dr[i];
      int nc = c+dc[i];
      if (nr < 0 || nr >= N || nc < 0 || nc >= M || A[nr][nc] < n)
        continue;
      ds.merge(conv(r, c), conv(nr, nc));
      sta.push(rc(nr, nc));
    }
  }
}
Пример #26
0
int main(void){
    int T;
    scanf("%d", &T);
    for(int kase = 1; kase <= T; kase++) {
        memset(v, 0, sizeof(v));
        int n, m;
        scanf("%d %d", &n, &m);

        DisjointSet d = DisjointSet(n + 1);
        bool flag = true;

        int i, j, pi = 0, pj = 0;
        while(m--) {
            scanf("%d %d", &i, &j);
            if(!flag) continue;
            v[i] = d.find(i);
            v[j] = d.find(j);

            if(d.find(i) == d.find(j))
                flag = false;

            if(d.find(pj) == v[i] || d.find(pi) == v[j]) {
                d.merge(i, pj);
                d.merge(j, pi);
            } else {
                d.merge(i, pi);
                d.merge(j, pj);
            }

            pi = i;
            pj = j;
        }

        printf("Scenario #%d:\n", kase);
        if(flag) printf("No suspicious bugs found!\n\n");
        else printf("Suspicious bugs found!\n\n");
    }
    return 0;
}
Пример #27
0
int main(){
    DisjointSet<int> s;
   
    /*
     *   you fill in here to set up the disjoint set 
     */
     s.createSet(1);
     s.createSet(2);
     s.createSet(3);
     s.createSet(4);
     s.createSet(5);
     s.createSet(6);
     s.createSet(7);
     s.createSet(8);
     s.createSet(9);
     
     s.unionSets(3,5);
     s.unionSets(4,2);
     s.unionSets(1,6);
     s.unionSets(5,7);
     s.unionSets(4,8);
     s.unionSets(3,7);
     s.unionSets(8,1);
    
    assert(s.findSet(1) == s.findSet(6)); // 1 and 6 are connected.
    assert(s.findSet(3) != s.findSet(6)); // 3 and 6 are not connected.
    assert(s.findSet(1) == s.findSet(1)); // 1 and 1 are connected.
    assert(s.findSet(3) == s.findSet(5)); // 3 and 5 are connected.
    assert(s.findSet(3) != s.findSet(9)); // 3 and 9 are not connected.
    
    cout<< "Done"<<endl;
}
int main(){

    DisjointSet graph;
    int t,a,b,n,k;
    char opc;

    scanf("%d",&t);

    for(int u=1;u<=t;u++){

        scanf("%d %d",&n,&k);

        graph.init(n);
        fill( pareja , pareja + n , -1 );

        for(int i=0;i<n;i++){
            scanf("%d",&a);
            if(a==0 || a-1==i) continue;
            a--;
            pareja[i] = a;
        }

        vector<pii> query;
        vector<pii> otro;

        while(k--){
            scanf("\n%c",&opc);

            if(opc=='C'){
                scanf("%d",&a);
                //printf("%c %d\n",opc,a);
                a--;
                b = pareja[a];
                if(b==-1) continue;
                pareja[a] = -1;
                query.push_back( pii( a , -1 ) );
                otro.push_back( pii( a , b ) );
            }
            else{
                scanf("%d %d",&a,&b);
                //printf("%c %d %d\n",opc,a,b);
                a--,b--;
                query.push_back( pii( a , b ) );
            }
        }

        for(int i=0;i<n;i++)
            if(pareja[i]!=-1)
                graph.join( i , pareja[i] );

        vector<string> res;
        int j = otro.size() - 1;

        for(int i=query.size()-1;i>=0;i--){
            if(query[i].second!=-1){
                if( graph.joined( query[i].second , query[i].first ) )
                    res.push_back("YES\n");
                else res.push_back("NO\n");
            }
            else{
                graph.join( otro[j].first , otro[j].second );
                j--;
            }
        }

        printf("Case #%d:\n",u);
        for(int i=res.size()-1;i>=0;i--)
            printf("%s",res[i].c_str());
    }
    return 0;
}
Пример #29
0
#define DISJOINT_SET_TEST

#include "third_party/catch.hpp"
#include "data_structures/disjoint_set.cpp"

TEST_CASE("Create a large set containing 10^8 elements", "[disjoint-set]") {
    /*
        Note: This test requires around 800MB of memory.
    */
    DisjointSet ds(1e8);
    REQUIRE(ds.size() == 1e8);
}

TEST_CASE("Check initial state", "[disjoint-set]") {
    DisjointSet ds(20);

    for (size_t element = 0; element < ds.size(); element++) {
        REQUIRE(ds.find(element) == element);
    }
}

TEST_CASE("Connect elements and verify their representatives", "[disjoint-set]") {
    DisjointSet ds(16);     // create a disjoint-set with elements from 0 to 15

    ds.join(0, 8);
    REQUIRE(ds.find(0) == 0);
    REQUIRE(ds.find(8) == 0);

    ds.join(3, 15);
    REQUIRE(ds.find(3) == 3);
    REQUIRE(ds.find(15) == 3);
Пример #30
0
 DisjointSet(const DisjointSet& copy) {
     left(copy.left());
     right(copy.right());
 }