Я пытаюсь решить Задача UVA Online Judge и я использую UFDS для ее решения. Проблема в том, что когда я запускаю код подряд, скажем, 5 раз, вывод отличается как минимум дважды, иногда даже показывая ошибку, которой не было в прошлый раз.
Я не могу найти проблему, и если это что-то очевидно, то заранее извиняюсь.
Вход для проблемы находится на странице, связанной выше.
Просто добавлю сюда ввод для удобства:
2
(A,B)
(B,C)
(B,D)
(D,E)
(E,F)
(B,G)
(G,H)
(G,I)
(J,K)
(K,L)
(K,M)
****
A,B,C,D,E,F,G,H,I,J,K,L,M,N
(A,B)
(A,C)
(C,F)
**
A,B,C,D,F
Код:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <queue>
#include <math.h>
#include <assert.h>
#include <set>
#include <map>
#include <bitset>
#include <ctime>
#include <time.h>
#include <algorithm>
#include <cstdio>
#include <fstream>
#include <stack>
#include <ctype.h>
#include <numeric>
#include <sstream>
#include <unistd.h>
#include <unordered_map>class UnionFind{
std::vector<int> p, rank, setSize;
int numSets;
public:
UnionFind(int n){
p.assign(n, 0);
rank.assign(n, 0);
setSize.assign(n, 1);
numSets = n;
for(int i = 0; i < n; ++i)p[i] = i;
}
int findSet(int i){
return (p[i] == i) ? i : (p[i] = findSet(p[i]));
}
bool isSameSet(int i, int j){
return (findSet(i) == findSet(j));
}
void unionSet(int i,int j){
if(!isSameSet(i, j)){
numSets--;
int x = findSet(i), y = findSet(j);
if(rank[x] > rank[y]){
p[y] = x;
setSize[x] += setSize[y];
}
else {
p[x] = y;
setSize[y] += setSize[x];
if(rank[x] == rank[y])rank[y]++;
}
}
}
int numDisjointSets(){
return numSets;
}
int sizeOfSet(int i){
return setSize[findSet(i)];
}
};
int main()
{
std::vector<std::pair<int, int>> edgelist;
std::vector<int> V;
int n;
std::cin >> n;
std::cin >> std::ws;
while(n--){
edgelist.clear();
V.clear();
std::string tmp;
while(std::getline(std::cin, tmp)){
if(tmp[0] == '*'){
break;
}
char a, b;
sscanf(tmp.c_str(), "(%c,%c)\n", &a, &b);
edgelist.emplace_back((int)a - 65, (int)b - 65); // to set A -> 0, B -> 1 etc.
}
char z;
std::getline(std::cin, tmp);
std::stringstream ss(tmp);
while(ss >> z){
if(z == ',')continue;
V.push_back((int)z - 65);
}
int m = (int)V.size();
UnionFind test(m);
for(int i = 0; i < (int)edgelist.size(); ++i){
test.unionSet(edgelist[i].first, edgelist[i].second);
}
int tree = test.numDisjointSets(), acorn = 0;
for(int i = 0; i < m; ++i){
if(test.sizeOfSet(i) == 1){
acorn++;
tree--;
}
}
printf("There are %d tree(s) and %d acorn(s).\n", tree, acorn);
}
}
Выход:
/*
Run 1:
There are 2 tree(s) and 1 acorn(s).
There are 0 tree(s) and 2 acorn(s).
Run 2:
There are 2 tree(s) and 1 acorn(s).
There are 0 tree(s) and 2 acorn(s).
Run 3:
There are 2 tree(s) and 1 acorn(s).
There are 1 tree(s) and 2 acorn(s).
Run 4:
There are 2 tree(s) and 1 acorn(s).
There are 0 tree(s) and 2 acorn(s).
Run 5:
There are 2 tree(s) and 1 acorn(s).
There are 1 tree(s) and 2 acorn(s).
*/
Задача ещё не решена.
Других решений пока нет …