I am trying to complete this challenge. The user should enter a sequence of instructions, =
to link two numbers, and ?
to query whether two integers are linked. For example,
? 1 2
= 1 5
= 2 5
? 1 2
should produce
no
yes
I have tried following the algorithm given here to the letter, but I keep getting a judgment of "time limit exceeded". It's very infuriating as the difficultly rating for the problem suggests it should be quite easy. I have tried modifying the code so that redundant links (e.g. = 1 2
where 1
is never queried nor later linked to another number) are ignored, but it still isn't fast enough.
#include <iostream>
#include <vector>
using namespace std;
int root(int a, vector<int> & parent) {
int b = parent[a];
return b == a ? a : parent[a] = root(b, parent);
}
void link(int a1, int a2, vector<int> & parent, vector<int> & rk) {
int root1 = root(a1, parent);
int root2 = root(a2, parent);
if (root1 == root2)
return;
int rk1 = rk[root1];
int rk2 = rk[root2];
if (rk1 < rk2) {
parent[root1] = root2;
} else if (rk2 < rk1) {
parent[root2] = root1;
} else {
parent[root1] = root2;
rk[root2]++;
}
}
int main() {
int n, q;
cin >> n >> q;
vector<int> parent;
for (int i = 0; i < n; i++)
parent.push_back(i);
vector<int> rk(n, 0);
for (int i = 0; i < q; i++) {
string str;
int a, b;
cin >> str >> a >> b;
if (str == "?")
cout << (a == b || root(a, parent) == root(b, parent) ? "yes" : "no") << endl;
else
link(a, b, parent, rk);
}
return 0;
}