简体   繁体   中英

Unknown run time error when submitting c++ program to Kattis online judge

I have been trying to submit my solution to the Kattis problem Almost Union Find , my solution passes the first test case but on the second test case it receives a Run Time Error. I get the message "Exited with signal 11 (SIGSEV)" , meaning segmentation violation. However, I have no idea what is cause of the error and am new to programming in c++ so any help would be greatly appreciated.

My program:

#include <cstdlib>
#include <cstdio>
#include <vector>
#include <unordered_set>

using namespace std;
typedef vector<int> vi;

unordered_set<int> seen(100000);

class UnionFind{
    private: vi p, rank;
    public:
             UnionFind(int N){
                 p.assign(N,0);
                 rank.assign(N,0);
                 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)){
                     int x = findSet(i), y = findSet(j);
                     if(rank[x] > rank[y]) p[y] = x;
                     else{
                         p[x] = y;
                         if(rank[x] == rank[y]) rank[y]++;
                     }
                 }
             }
             void moveSet(int i, int j){
                 if(!isSameSet(i,j)){
                     int x = findSet(j);
                     p[i] = x;
                 }
             }
             void printVals(int i){
                 int sum = 0;
                 int counter = 0;
                 for(auto itr = seen.begin(); itr != seen.end(); ++itr){
                     if(isSameSet(i,*itr)){
                         sum += *itr;
                         ++counter;
                     }
                 }
                 printf("%d %d\n",counter,sum);
             }
};

int main() {
    int N, M;
    while(scanf("%d %d",&N, &M) != EOF){
        UnionFind uf(M);
        for(int i = 0; i < M; i++){
            int a,b,c;
            scanf("%d %d",&a, &b);
            //printf("a:%d b:%d c:%d\n",a,b,c);
            if(a == 1){
                scanf("%d",&c);
                seen.insert(b);
                seen.insert(c);
                uf.unionSet(b,c);
            }
            else if(a == 2){
                scanf("%d",&c);
                seen.insert(b);
                seen.insert(c);
                uf.moveSet(b,c);
            }
            else if(a == 3){
                uf.printVals(b);
            }
        }
        seen.clear();
    }
    return 0;
}

You should show us the input values that are causing the error.

Anyway... in UnionFind methods you access the p and rank vectors; but are you sure that you're accessing to allocated positions?

That is: are you sure that when you call (by example)

p[i]

in findset() , i is lower that p.size() ?

Suggestion: substitute all calls to operator[] (that operate without bound check) with calls to at() (that do a bound check and throw an exception if it fails)

So p.at(i) instead of p[i] and rank.at(x) instead of rank[x] in all methods of UnionFind .

If the problem is here, you should get an exception instead of a sigsegv.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM