0
#include <iostream>
#include <vector>
#include <cassert>
#include <queue>

using namespace std;
struct vectors{
    int x;
    int y;
    bool visited;
    vectors(int x = 0, int y = 0){
        this -> x = x;
        this -> y = y;
        visited = false;
    }
    bool isNotFound(){
        return visited == false;
    }

    void setZero(){
        x = 0;
        y = 0;
    }
    vectors operator+(vectors others){
        return vectors(x + others.x, y + others.y);
    }
    vectors operator*(int others){
        return vectors(x * others, y * others);
    }

};

struct node{
    int adjFarm;
    int length;
    char direction;
    node(int f, int l, char d){
        adjFarm = f;
        length = l;
        direction = d;
    }

};
int num_villages;

char inverse_direction(char d){
    assert(d == 'N' || d == 'E' || d == 'W' || d == 'S' );
    switch(d){
        case 'S': return 'N';
        case 'N': return 'S';
        case 'E': return 'W';
        case 'W': return 'E';
    }
}

void AddToPaths(int farm1, int farm2, char direction, int length, vector< vector<node> > &pathGraph){
    pathGraph.at(farm1).push_back(node(farm2, length, direction));
    pathGraph.at(farm2).push_back(node(farm1, length, inverse_direction(direction)));

}
vectors directionVector(int d){
    switch(d){
        case 'N': return vectors(0, 1);
        case 'E': return vectors(1, 0);
        case 'W': return vectors(- 1, 0);
        case 'S': return vectors(0, - 1);
    }
}
void print_coords(vector< vectors > coords){
    for(int i = 1; i < num_villages + 1; i ++){
        cout << "farm: " << i << " coordinates x at farm: " << coords.at(i).x << " coordinated y at farm: " << coords.at(i).y << endl;

    }
}

void update(char direction, int newFarm, int length, int currentFarm, vector <vectors> &coords){
    vectors directions = directionVector(direction);
    coords.at(newFarm) = coords.at(currentFarm) + directions * length;
    coords.at(newFarm).visited = true;
}

void computeCoords(vector <vectors> &coords, vector< vector<node> > &pathGraph){
    queue <int> frontier;
    frontier.push(1);
    coords.at(1).visited = true;
    while(!frontier.empty()){
        int currentFarm = frontier.front();
        frontier.pop();
        for(int i = 0; i < pathGraph.at(currentFarm).size(); i ++){
            node options = pathGraph.at(currentFarm).at(i);
            if(coords.at(options.adjFarm).isNotFound()){
                update(options.direction, options.adjFarm, options.length, currentFarm, coords);
                frontier.push(options.adjFarm);
            }
        }
    }
}
struct UnionFind{
    vector<int> L;
    UnionFind(int num_villages){
        L.resize(num_villages + 1);
        for(int i = 1; i <= num_villages; i ++){
            L.at(i) = i;
        }
    }
    int find(int x){
        if(x == L.at(x)) return x;
        int root = find(L.at(x));
        L.at(x) = root;
        return root;
    }
    int Union(int x, int y){
        int root1 = find(x);
        int root2 = find(y);
        L.at(y) = root1;
    }


};

int pos;
int query(int start, int destination, int order, UnionFind &reachables, vector<vectors> &coords, vector<vector<int> > &source_destination_order){
    while(pos <= order){
        reachables.Union(reachables.find(source_destination_order.at(pos).at(0)), reachables.find(source_destination_order.at(pos).at(1)));
       pos ++;
    }
    if(reachables.find(start) == reachables.find(destination)){
        return abs(coords.at(start).x - coords.at(destination).x) + abs(coords.at(start).y - coords.at(destination).y);
    }
    else{
        return -1;
    }
}

int main(void){
    int num_roads;
    cin >> num_villages;
    cin >> num_roads;
    vector <vector<node> > pathGraph(num_villages + 1);
    vector <vectors > coords(num_villages + 1);
    vector <vector <int> > source_destination_order(num_villages + 1, vector<int> (2));
    //Adding inforamtion about the farms
    int farm1;
    int farm2;
    char direction;
    int length;
    int source;
    for(int i = 0; i < num_roads; i ++){
        cin >> farm1;
        cin >> farm2;
        cin >> length;
        cin >> direction;
        AddToPaths(farm1, farm2, direction, length, pathGraph);
        source_destination_order.at(i + 1).at(0) = farm1;
        source_destination_order.at(i + 1).at(1) = farm2;

    }
    computeCoords(coords, pathGraph);

    int numQueries;


    cin >> numQueries;
    int start;
    int destination;
    int order;
    int result;
    UnionFind reachables(num_villages);
    pos = 1;
    for(int i = 0; i < numQueries; i ++){
        cin >> start;
        cin >> destination;
        cin >> order;
        result = query(start, destination, order, reachables, coords, source_destination_order);
        cout << result << endl;
    }


}

I tried to create an undirected acyclic graph with the farms as the vertices and the roads as the edges, and then use BFS to compute the coordinates of each farm relative to the first farm. Afterwards I used the union find structure to create disjoint sets of farms that are reachable from each other at the time of the query. However, it seems like my code takes too long to run, how should I fix it?

Dominique Fortin
  • 2,212
  • 15
  • 20
Jarry
  • 9
  • 1
  • 2
    Please explain the problem you're trying to solve (in programming terms), instead of relying on (links to) third-party sites. – m69's been on strike for years Sep 02 '18 at 21:47
  • Hmm, I think you're expected to integrate the coordinate determinations into the union-find structure. – David Eisenstat Sep 02 '18 at 22:06
  • Haven't coded it up, but I think there's a solution where each operation runs as fast as union-find up to constant factors. – David Eisenstat Sep 02 '18 at 22:08
  • Sorry, when you say that I have to integrate the coordinate determination into the union find structure you're saying, as I use the Union operation to unify two sets of farms, I have to update the coordinates of one set to match the coordinates of the other? – Jarry Sep 03 '18 at 01:36
  • Unions stay the same, but find and path compression have to sum the coordinate deltas. – David Eisenstat Sep 03 '18 at 02:31

0 Answers0