Read in a matrix and build a graph - c++

I have a rectangular room; its' floor is coverd with floor boards, some of them are broken.
The dimensions of the room are N and M: 1 <=N,M<=300.
I read N and M from stdin, and then I read N strings of length M, which look like this:
..**.***....*.**...**.***
.**......**...***..***...
and so on, where . is a good floor board and * is a broken one.
I intend to replace the broken floor boards with new one, and I only have two types of those: two-by-ones and one-by-ones. I can't cut the two-by-ones into two one-by-ones.
To find a way to do this, I paint the floor like a checkerboard, so that the halves of a broken two-by-one are of different color.
Then I mean to build a bipartite graph (consisting of a white and a black part) from the resulting matrix, and I'd like to build and analyse it with this code.
What's the best way to do that?
I think that I shouldn't keep all the matrix in memory (since it can be rather large). Ideally I should be able to read in strings and update the graph on the run.
EDIT:
My code should like this:
int main()
{
int N, M;
std::cin >> N;
assert (( N >=1) && (N <=300));
std::cin >> M;
assert (( M >=1) && (M <=300));
for (int i = 0; i < N; ++i)
std::cin >> // that's where I have to read the string
//...and the next string
// use these 2 strings to update a graph
// with prGraph.AddEdge()
return 0;
}

If it is really so important not to store the entire matrix in memory, you can read it line by line and store only the current and the previous line because it is sufficient to construct a graph properly.

A naive graph construction using an adjacency matrix would take 300x300 ^2, which is tough to fit in memory.
You can take advantage of the fact that each vertex can have at most 4 edges - you would only need space on order of 300 x 300 x 4 using adjacency lists for your maxflow instead, as long as you change the graph traversal accordingly.

Related

Tiling a 2xM array with 2x1 tiles to maximise the differences - INOI 2008, P2

(As I am new and may not be aware of the code of conduct, feel free to edit this post to make this better and more helpful to other people.)
Greetings everybody!
This problem is related to this: Problem Link
The problem in brief:
Given a 2xM array and we want to tile it with 2x1 tiles such that the sum of absolute values of the differences of the values "covered" via the individual tiles is maximized. We want to report this max sum.
The problem in detail:
In Domino Solitaire, you have a grid with two rows and many columns. Each square in the grid contains an integer. You are given a supply of rectangular 2×1 tiles, each of which exactly covers two adjacent squares of the grid. You have to place tiles to cover all the squares in the grid such that each tile covers two squares and no pair of tiles overlap. The score for a tile is the difference between the bigger and the smaller number that are covered by the tile. The aim of the game is to maximize the sum of the scores of all the tiles.
Below is my code for it. Basically, I've done a sort of a recursive thing because there are two cases: (1) One vertical 2x1 tile in the start and (2) Two horizontal 2x1 laid together to cover 2 columns.
#include <bits/stdc++.h>
using namespace std;
int maxScore(int array[][2], int N, int i);
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int N; cin >> N;
int array[N][2]; for(int i=0;i<N;i++) cin >> array[i][0] >> array[i][1];
cout << maxScore(array, N, 0);
return 0;
}
int maxScore(int array[][2], int N, int i){
int score1 = abs(array[i][0] - array[i][1]) + maxScore(array, N, i+1);
int score2 = abs(array[i][0] - array[i+1][0]) + abs(array[i][1] - array[i+1][1]) + maxScore(array, N, i+2);
return max(score1, score2);
}
However, this seems to be a very inefficient solution and I can't really understand how to cover the base cases (otherwise this would go on forever).
Any help would be really appreciated. Thank You! (BTW I want to create a new tag - Competitive Programming, can anybody help me do so?)
Maintain an array of the best solutions, where the value in column i of the array is the best solution considering only the matching colums of the input matrix. Then arr[i] = max possible by adding either one tile to the arr[i-1] solution, or 2 to the arr[i-2] solution. Treat arr[-1] as 0 and set arr[0] to the val of one vertical dominoe.
This is intentionally not a complete solution, but should help you find a much faster implementation.
Since you need to cover every square of a 2xM grid, there is no way you have dominoes placed like this:
. . .[#|#]. .
. .[#|#]. . .
So essentially, for every sub-block the right most domino is vertical, or there are two horizontal ones above each other.
If you start from the left, you only need to remember what your best result was for the first n or n-1 tiles, then try placing a vertical domino right to the n-solution or two horizontal dominoes right to the n-1 solution. The better solution is the best n+1 solution. You can compute this in a simple for-loop, as a first step, store all partial solutions in a std::vector.

Unable to Input the graph

I am solving the problem http://www.spoj.com/problems/SHOP/ in C++ but I am unable to figure out how to input the graph to furhter apply Dijkstra algorithm in it.
Here is the graph format-
4 3
X 1 S 3
4 2 X 4
X 1 D 2
First line indicated the columns & rows of the grid ,"S" & "D" -indicates source and destination respetively Numbers -indicates the time required to pass that block,"X"-indicates the no entry zone.
HOw to convert the following graph in nodes and edges as required by DIjkstra algorithm.I don't know how to convert the map into a graph.
There is no need to convert. Just imagine that you are in some point (i,j). (I assume that you have four moves allowed from each square). Then, you can go to either (i + 1, j), (i, j + 1), (i - 1, j), (i, j - 1) if:
1) That index is inside the table
2) That index is not marked with X
So, you give the position of square S to your Dijkstra algorithm. And each time you add the new set of allowed squares to your data structure. Once your reach the position of D you print it.
Besides, this problem does not seem weighted to me so you can use a simple BFS as well using a queue. But if you want to use Dijkstra and going to different squares has different costs. The you use a priority queue instead of queue.
For example, you can use a set data structure like this:
int dist[][]; // this contains the cost to get to some square
//dist is initialized with a large number
struct node{
int i, j; //location
node(int ii, int jj){
i = ii;
j = jj;
}
bool operator < (node &n)const{ //set in c++ will use this to sort
if(dist[i][j] == dist[n.i][n.j]) return i < n.i || j < n.j; //this is necessary
return dist[i][j] < dist[n.i][n.j];
}
};
set <node> q;
int main(){
//initialized dist with large number
dist[S.i][S.j] = 0; //we start from source
q.push(node(S.i, S.j));
while(true){
//pick the first element in set
//this element has the smallest cost
//update dist using this node if necessary
//for every node that you update remove from q and add it again
//this way the location of that node will be updated in q
//if you see square 'D' you are done and you can print dist[D.i][D.j]
}
return 0;
}
There is no need to convert the matrix into nodes and edges.
You can make structure which contain (row number,column number ,time ) where time will represent how much time taken to reach this coordinate from source. now make a min heap of this structure with key as time. now extract element (initially source will be in min heap with time as 0) from min heap and push the adjacent elements into min heap(only those elements which are not visited and do not contain a X) set visited of extracted element true.Go on like this until extracted element is not destination.

C++ creating a graph out of dot coordinates and finding MST

I'm trying to make a program in which the user inputs n dot coordinates, 0 < n <= 100. Supposedly, the dots have to be connected, lets say, with ink in a way that you can get e.g from point A to point X while following the inked line and using the least amount of ink possible.
I thought of using Prim Algorithm or something like that to get the MST but for that I need a graph. In all the webpages I've looked they don't really explain that, they always already have the graph with its edges already in there.
I need help specifically creating a graph in C++ out of a bunch of (x, y) coordinates, like the user inputs:
0 0
4 4
4 0
0 4
Please note I'm just starting with C++ and that I can't use any weird libraries since this would be for a page like CodeForces where you only get to use the native libraries.
(For the ones that are also doing this and are here for help, the correct output for this input would be 12)
To assume a complete graph may be most appropriate as suggested by "Beta".
Following code may creates edges between every pair of two dots from a list of dots in the array dots and returns the number of edges created.
After execute this code, you may be able to apply Prim Algorithm for finding MST.
// Definition of Structure "node" and an array to store inputs
typedef struct node {
int x; // x-cordinate of dot
int y; // y-cordinate of dot
} dots[100];
// Definition of Structure "edge"
typedef struct edge {
int t1; // index of dot in dots[] for an end.
int t2; // index of dot in dots[] for another end.
float weight; // weight (geometric distance between two ends)
} lines[];
// Function to create edges of complete graph from an array of nodes.
// Argument: number of nodes stored in the array dots.
// ReturnValue: number of edges created.
// Assumption: the array lines is large enough to store all edges of complete graph
int createCompleteGraph(int numberOfNodes){
int i,j,k,x-diff,y-diff;
k=0; // k is index of array lines
for (i=0; i<numberOfNodes-1; i++) {// index of a node at one end
for (j=i+1; j<numberOfNodes; j++) {// index of a node at another end
lines[k].t1 = i;
lines[k].t2 = j;
x-diff = dots[i].x - dots[j].x;
y-diff = dots[i].y - dots[j].y;
lines[k].weight = sqrt(x-diff * x-diff + y-diff * y-diff) // calculate geometric distance
k++;
}
}
return k;
}

Use map instead of array in C++ to protect searching outside of array bounds?

I have a gridded rectangular file that I have read into an array. This gridded file contains data values and NODATA values; the data values make up a continuous odd shape inside of the array, with NODATA values filling in the rest to keep the gridded file rectangular. I perform operations on the data values and skip the NODATA values.
The operations I perform on the data values consist of examining the 8 surrounding neighbors (the current cell is the center of a 3x3 grid). I can handle when any of the eight neighbors are NODATA values, but when actual data values fall in the first or last row/column, I trigger an error by trying to access an array value that doesn't exist.
To get around this I have considered three options:
Add a new first and last row/column with NODATA values, and adjust my code accordingly - I can cycle through the internal 'original' array and handle the new NODATA values like the edges I'm already handling that don't fall in the first and last row/column.
I can create specific processes for handling the cells in first and last row/column that have data - modified for loops (a for loop that steps through a specific sequence/range) that only examine the surrounding cells that exist, though since I still need 8 neighboring values (NODATA/non-existent cells are given the same value as the central cell) I would have to copy blank/NODATA values to a secondary 3x3 grid. Though there maybe a way to avoid the secondary grid. This solution is annoying as I have to code up specialized routines to all corner cells (4 different for loops) and any cell in the 1st or last row/column (another 4 different for loops). With a single for loop for any non-edge cell.
Use a map, which based on my reading, appears capable of storing the original array while letting me search for locations outside the array without triggering an error. In this case, I still have to give these non-existent cells a value (equal to the center of the array) and so may or may not have to set up a secondary 3x3 grid as well; once again there maybe a way to avoid the secondary grid.
Solution 1 seems the simplest, solution 3 the most clever, and 2 the most annoying. Are there any solutions I'm missing? Or does one of these solutions deserve to be the clear winner?
My advice is to replace all read accesses to the array by a function. For example, arr[i][j] by getarr(i,j). That way, all your algorithmic code stays more or less unchanged and you can easily return NODATA for indices outside bounds.
But I must admit that it is only my opinion.
I've had to do this before and the fastest solution was to expand the region with NODATA values and iterate over the interior. This way the core loop is simple for the compiler to optimize.
If this is not a computational hot-spot in the code, I'd go with Serge's approach instead though.
To minimize rippling effects I used an array structure with explicit row/column strides, something like this:
class Grid {
private:
shared_ptr<vector<double>> data;
int origin;
int xStride;
int yStride;
public:
Grid(int nx, int ny) :
data( new vector<double>(nx*ny) ),
origin(0),
xStride(1),
yStride(nx) {
}
Grid(int nx, int ny, int padx, int pady) :
data( new vector<double>((nx+2*padx)*(ny+2*pady));
xStride(1),
yStride(nx+2*padx),
origin(nx+3*padx) {
}
double& operator()(int x, int y) {
return (*data)[origin + x*xStride + y*yStride];
}
}
Now you can do
Grid g(5,5,1,1);
Grid g2(5,5);
//Initialise
for(int i=0; i<5; ++i) {
for(int j=0; j<5; ++j) {
g(i,j)=i+j;
}
}
// Convolve (note we don't care about going outside the
// range, and our indices are unchanged between the two
// grids.
for(int i=0; i<5; ++i) {
for(int j=0; j<5; ++j) {
g2(i,j)=0;
g2(i,j)+=g(i-1,j);
g2(i,j)+=g(i+1,j);
g2(i,j)+=g(i,j-1);
g2(i,j)+=g(i,j+1);
}
}
Aside: This data structure is awesome for working with transposes, and sub-matrices. Each of those is just an adjustment of the offset and stride values.
Solution 1 is the standard solution. It takes maximum advantage of modern computer architectures, where a few bytes of memory are no big deal, and correct instruction prediction accelerates performance. As you keep accessing memory in a predictable pattern (with fixed strides), the CPU prefetcher will successfully read ahead.
Solution 2 saves a small amount of memory, but the special handling of the edges incurs a real slowdown. Still, the large chunk in the middle benefits from the prefetcher.
Solution 3 is horrible. Map access is O(log N) instead of O(1), and in practice it can be 10-20 times slower. Maps have poor locality of reference; the CPU prefetcher will not kick in.
If simple means "easy to read" I'd recommend you declare a class with an overloaded [] operator. Use it like a regular array but it'll have bounds checking to handle NODATA.
If simple means "high performance" and you have sparse grid with isolated DATA consider implementing linked lists to the DATA values and implement optimal operators that go directly to tge DATA values.
1 wastes memory proportional to your overall rectangle size, 3/maps are clumsy here, 2 is actually very easy to do:
T d[X][Y] = ...;
for (int x = 0; x < X; ++x)
for (int y = 0; y < Y; ++y) // move over d[x][y] centres
{
T r[3][3] = { { d[i,j], d[i,j], d[i,j] },
d[i,j], d[i,j], d[i,j] },
d[i,j], d[i,j], d[i,j] } };
for (int i = std::min(0, x-1); i < std::max(X-1, x+1); ++i)
for (int j = std::min(0, y-1); j < std::max(Y-1, y+1); ++j)
if (d[i][j] != NoData)
r[i-x][j-y] = d[i][j];
// use r for whatever...
}
Note that I'm using signed int very deliberately so x-1 and y-1 don't become huge positive numbers (as they would with say size_t) and break the std::min logic... but you could express it differently if you had some reason to prefer size_t (e.g. x == 0 ? 0 : x - 1).

Help with geometry problem - don't have any idea

I am preparing myself for programming competitions and i would like to know how can i solve this problem. I guess it's geometry problem, and it seems i can't get any ideas about solving it.
Here it is:
There is a yard in which there are wolves and sheep. In the yard there are also blocks which do not allow to pass. The wolves are represented with 'w' and the sheep with 's', while the blocks are with '#' and the space where everyone can move is '.' . So a possible input will look like:
8 8
.######.
#..s...#
#.####.#
#.#w.#.#
#.#.s#s#
#s.##..#
#.w..w.#
.######.
The 2 numbers above the yard are rows x columns.
As you can see, by this there can be formed sectors of different kind in the yard. Here are two sectors:
####
#.w#
####
#s.#
In the first one there is a wolf and in the second a sheep. Because they are placed in two different sectors (i.e. the wolf can't get to the sheep), he can't eat it. If they were in a same sector, the wolf would eat the sheep.
My question for you is this: Given an input like the ones above, how should i calculate how many sheep will survive ? How can i represent the 'yard' in c++ ? How should the algorithm looks like ? Are there any materials for understanding similar problems and issues ?
Any help is appreciated. Thank you in advance.
This problem is basically a problem of finding connected sub-graphs (aka components) for a given graph.
You can solve the problem by representing each "non-block" coordinate as a graph node, linking the 2 neighboring coordinates in a graph. Then find connected subgraphs using BFS (or any other algorithm suitable for the topic - I'm sure any web page or Wiki on graph algos will have a list of assorted algorithms on that.
Once you have your subgraphs, just find which subgraphs have zero wolves (by finding which subgraph each wolf coordinate is on), and count sheep in those subgraphs .
Hope this is enough for you to start.
What you are looking for here is to find the connected components of the graph, then you just need to count the number of wolves and sheep in each one.
using namespace std;
int w, h;
cin >> w >> h;
vector<string> grid(h);
for (int i = 0; i < h; ++i)
cin >> grid[i];
vector< vector<bool> > seen(h, vector<bool>(w, false));
int survived = 0;
const int mx[] = {-1, 0, 1, 0}, my[] = {0, -1, 0, 1};
for (int i = 0; i < h; ++i)
for (int j = 0; j < w; ++j)
if (!seen[i][j] && grid[i][j] != '#')
{
int sheep = 0, wolves = 0;
typedef pair<int, int> point;
stack<point> s;
s.push(point(i, j));
while (!s.empty())
{
point p = s.top();
int x = p.first, y = p.second;
if (grid[x][y] == 'w') wolves++;
if (grid[x][y] == 's') sheep++;
for (int k = 0; k < 4; ++k)
{
int x2 = x + mx[k], y2 = y + my[k];
if (x2<0 || x2>=h || y2<0 || y2>=w) continue;
if (grid[x2][y2] == '#' || seen[x2][y2]) continue;
s.push(point(x2, y2));
}
}
survived += max(0, sheep - wolves);
}
cout << "Surviving sheep = " << survived << endl;
Running time and memory usage is optimal at O(rows x columns).
Note that code is untested, but I believe this should work.
A simple approach would be to do a flood fill starting on each wolf. You can assume that each wolf will move (flood fill) the dots around him. After you flood fill starting from all the dots, any remaining sheep will survive.
In your example:
####
#.w#
####
#s.#
would fill to:
####
#fw#
####
#s.#
(I used f for the filled space), and the algorithm will stop, so s will survive.
maybe try thinking of the yard as a group of sectors. when creating a sector, if there is a wolf in it, remove all sheep. Now the only challenge is representing a sector, which seems much more manageable.
Consider using the logic of flood filling algorithms.
Doesn't look like a geometry problem to me. I would solve it with the Flood fill algorithm
Fill every area with a unique number. Then, for every number you filled an area with, find out how many sheep and how many wolves are adjacent to that number. The only surviving sheep are those that are adjacent to a number k that no wolves are adjacent to.
You can represent the matrix in C++ as a matrix of chars: char A[maxrows][maxcols]. However, to use flood fill, I would use a matrix of ints, because you might have more areas than the max value of a char.
Is this a time-limited competition? E.g., one where your score is a function of the number of programs solved in a given time?
For these I would recommend a simple approach based on two things:
Represent the data as a 2D array
Determine when sheep and wolves share a sector by searching connectivity, using something like a flood-fill algorithm from each wolf. I would recommend starting from the wolves and "killing off" sheep when you reach them. After you do this for each wolf, any remaining sheep in the data structure survive.
The key in the time-limited competitions is to come up with a simple solution that's quick to program. Modern computers are extremely fast. Don't think about geometric algorithms unless you need to be able to handle vast data sets, just think how could I throw computation at the problem to solve it easily.
While I thought about this several other people suggested flood-filling, so this is somewhat redundant.