Reputation: 27
In the following code segment, the cin
inside the while
loop, which is nested inside the while
loop in the main
function, is somehow not working during the last input (i.e, when h == n-1
) and reporting a segmentation fault instead.
I figured this out by using the print
statements (which are commented in the code below), one at the start of the inner while
loop, one after the cin
statement (to find the read values of v
and x
decremented by 1) and one outside the while
loop. The third cout
statement doesn't execute, from which I concluded that the segmentation fault is inside the while
loop.
Moreover, in the last iteration of the inner while
loop, the cout
statement after the cin
statement (to print the values of v
and x
) also didn't execute. And so, I think that the cin
inside the inner while
loop isn't working in the last iteration.
I tried searching a lot and put in the cin.clear()
and cin.ignore(numeric_limits<streamsize>::max(), '\n');
statements but still no use!
Why is there such an issue?
#include <bits/stdc++.h>
using namespace std;
vector <vector<int>> adj;
vector<unordered_set <int>> leaf;
int process(int node, int *pans, int k){
*pans = *pans + (leaf[node].size() / k) * k;
int temp = (leaf[node].size() / k) * k;
if(temp == 0) return 0;
for(auto it : leaf[node]){
if(temp == 0) break;
leaf[node].erase(it);
auto j = find(adj[node].begin(), adj[node].end(), it);
adj[node].erase(j);
temp --;
}
if(adj[node].size() == 1){
leaf[adj[node][0]].insert(node);
process(adj[node][0], pans, k);
}
return 0;
}
int main(){
int t, v, x, n, k;
cin>>t;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
while(t--){
int ans = 0;
cin>>n>>k;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
adj.resize(n);
int h = 1;
while(h < n){
// cout<<"r";
cin>>v>>x;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
v --; x --;
cout<<v<<" "<<x<<"\n";
adj[v].push_back(x);
adj[x].push_back(v);
h++;
}
// cout<<"out";
leaf.resize(n);
for(int i = 0; i < n; i ++){
if(adj[i].size() == 1) leaf[adj[i][0]].insert(i);
}
for(int i = 0; i < n; i ++){
if(leaf[i].size() >= k) process(i, &ans, k);
}
cout<<ans<<"\n";
adj.clear();
leaf.clear();
}
}
Following is an example of the input:
1
8 3
1 2
1 5
7 6
6 8
3 1
6 4
6 1
Upvotes: 0
Views: 220
Reputation: 88027
The error is here
for(auto it : leaf[node]){
if(temp == 0) break;
leaf[node].erase(it);
auto j = find(adj[node].begin(), adj[node].end(), it);
adj[node].erase(j);
temp --;
}
By modifying the unordered_set leaf[node].erase(it);
you are invalidating the implicit iterator used by the range based for loop. Rewrite your loop with an explciit iterator so you can account for the iterator invalidation. Like this
for (auto i = leaf[node].begin(); i != leaf[node].end(); ) {
if(temp == 0) break;
auto it = *i;
i = leaf[node].erase(i);
auto j = find(adj[node].begin(), adj[node].end(), it);
adj[node].erase(j);
temp --;
}
With this loop your code runs to completion (at least for me). I've no idea if the output is correct or not.
Upvotes: 2