Dijkstra running slow - algorithm

There is a problem at Spoj called HIGHWAYS, that is basically to find the shortest path between 2 given cities.
The first time I solved it, I used Dijkstra algorithm... I got it right, although the code was kind of big, so I decided to redo it with smaller code (that obviously acts the same way), but it's getting Time Limit Exceeded.
I'd like to know what difference between them is making this TLE to happen.
The input is like this:
n //number of test cases
c e s e //number of cities (from 1 to c), number of edges, start and end cities
c1 c2 w //e lines, each with connection between c1 and c2 with weight w
Here are the long code (Accepted):
#include <bits/stdc++.h>
using namespace std;
#define si(n) scanf("%d", &n)
#define INF 99999
int d[100010];
struct edge {
int v, weight;
edge(int a, int w) {
v = a;
weight = w;
}
bool operator < (const edge & o) const {
return weight > o.weight;
}
};
struct vertex {
int value;
vector <edge> adj;
vertex() {
adj.clear();
}
vertex(int val) {
value = val;
adj.clear();
}
void add(edge a) {
adj.push_back(a);
}
};
struct graph {
vertex v[100010];
void add_v(int val) {
vertex a(val);
a.adj.clear();
v[val] = a;
}
void add_a(int v1, int v2, int p) {
v[v1].add(edge(v2, p));
v[v2].add(edge(v1, p));
}
void dijkstra(int n, int f) {
for(int i = 0; i <= f; i++ ) d[i] = INF;
priority_queue < edge > Q;
d[n] = 0;
int current;
Q.push(edge(n, 0));
while (!Q.empty()) {
current = Q.top().v;
Q.pop();
for (int i = 0; i < v[current].adj.size(); i++) {
edge a = v[current].adj[i];
if (d[a.v] > d[current] + a.weight) {
d[a.v] = d[current] + a.weight;
Q.push(edge(a.v, d[a.v]));
}
}
}
}
};
int main(){
int cases;
si(cases);
int v, a, ini, fim;
int v1, v2, w;
while(cases--){
si(v); si(a);
si(ini); si(fim);
graph g;
for(int i = 1; i <= v; i++){
g.add_v(i);
}
for(int i = 0; i < a; i++){
si(v1); si(v2); si(w);
g.add_a(v1, v2, w);
}
g.dijkstra(ini, v+1);
int dist = d[fim];
if(dist < 0 || dist >= INF) printf("NONE\n");
else printf("%d\n", dist);
}
}
Here is the short one (Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
struct edge{
int v, w;
edge(){}
edge(int a, int b){v = a; w = b;}
};
bool operator < (edge a, edge b) {return a.w < b.w;}
const int INF = INT_MAX;
typedef vector<vector<edge> > graph;
typedef priority_queue<edge> heap;
int d[100020];
void Dijkstra(graph G, int length, int s){
for(int i = 1; i <= length; i++) d[i] = INF;
edge base;
base.v = s;
base.w = d[s] = 0;
heap H;
H.push(base);
while(!H.empty()){
int current = H.top().v;
H.pop();
for (int i = 0; i < G[current].size(); i++) {
edge a = G[current][i];
if (d[a.v] > d[current] + a.w) {
d[a.v] = d[current] + a.w;
H.push(edge (a.v, d[a.v]));
}
}
}
}
int main(){
int cases;
int n, m, s, e;
int v1, v2, w;
scanf("%d", &cases);
while(cases--){
scanf("%d %d %d %d", &n, &m, &s, &e);
graph G(n + 1);
for(int i = 0; i < m; i++){
scanf("%d %d %d", &v1, &v2, &w);
G[v1].push_back(edge(v2, w));
G[v2].push_back(edge(v1, w));
}
Dijkstra(G, n, s);
if(d[e] != INF) printf("%d\n", d[e]);
else printf("NONE\n");
}
}

The difference is in how you control the priority queue. In the long version, you take the edges with a small weight first, which enables you to find the optimum earlier and cut many possible paths short:
bool operator < (const edge & o) const {
return weight > o.weight;
}
In the short version, you have the behaviour (accidentially?) reversed and always take the edge with the greatest weight, which means that you effectively probe all possible paths.
bool operator < (edge a, edge b) {return a.w < b.w;}
Change the inequality operator and both versions will run equally fast.

The containers of STL are slow. Avoid using vector if necessary.
here is my dij:
class graph
{
public :
int head[N],next[M],node[M];
int dist[M];
int tot;
void init()
{
tot = 0;
CLR(head,-1);
}
void add(int x,int y,int z = 1)
{
node[tot] = y;
dist[tot] = z;
next[tot] = head[x];
head[x] = tot++;
}
graph() {init();}
} g;
int dist[N]; ///the distance
///src means source. ter is optional, it means terminal
void dij(int src, graph &g, int ter=-1)
{
memset(dist,0x3f,sizeof(dist)); ///init d[i] as a very large value
dist[src] = 0;
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > pq;
pq.push(make_pair(dist[src],src));
while(!pq.empty())
{
int x = pq.top().second;
int d = pq.top().first;
if(d != dist[x])continue;
if(x == ter)return ;
for(int i = g.head[x] ; ~i ; i = g.next[i])
{
int y = g.node[i];
if(d+g.dist[i]<dist[y])
{
dist[y] = d + g.dist[i];
pq.push(make_pair(dist[y],y));
}
}
}
}

Related

How to find Time complexity of Graph coloring using backtracking?

I have to find out the time complexity of graph coloring problem using backtracking. I have found somewhere it is O(n*m^n) where n=no vertex and m= number of color.
Suppose my code is given below how to find time complexity?
bool isSafe (int v, bool graph[V][V], int color[], int c)
{
for (int i = 0; i < V; i++)
if (graph[v][i] && c == color[i])
return false;
return true;
}
bool graphColoringUtil(bool graph[V][V], int m, int color[], int v)
{
if (v == V)
return true;
for (int c = 1; c <= m; c++)
{
if (isSafe(v, graph, color, c))
{
color[v] = c;
if (graphColoringUtil (graph, m, color, v+1) == true)
return true;
color[v] = 0;
}
}
return false;
}
bool graphColoring(bool graph[V][V], int m)
{
int *color = new int[V];
for (int i = 0; i < V; i++)
color[i] = 0;
if (graphColoringUtil(graph, m, color, 0) == false)
{
printf("Solution does not exist\n");
return false;
}
printSolution(color);
return true;
}
void printSolution(int color[])
{
printf("Solution Exists:"
" Following are the assigned colors \n");
for (int i = 0; i < V; i++)
printf(" %d ", color[i]);
printf("\n");
}
The graphutil method will execute n times itself.It is in the c Loop,and c goes upto m .
Now the c loop goes n times due to recursion(i.e. m^n) and recursion goes n times,So total it will be O(nm^n )

Mapping a large number to a unique number using MOD operation

Let the Roots of a first degree polynomial( Q(x) ) be x0 = -b/a. Since the range of the variable a and b is large, x0 can be large as well for it to be stored in a variable(x0).
so, it is converted to some unique number using some operation with mod
int x0 = mul(mod - b, rev(a));
problem link: hackerank problem
Can someone please explain how this line of code works and the math behind this operation?
the whole code-
#include <bits/stdc++.h>
using namespace std;
#define forn(i,n) for (int i = 0; i < int(n); ++i)
typedef long long ll;
const int inf = int(1e9) + int(1e5);
const ll infl = ll(2e18) + ll(1e10);
const int mod = 1e9 + 7;
int udd(int &a, int b) {
a += b;
if (a >= mod)
a -= mod;
return a;
}
int add(int a, int b) {
return udd(a, b);
}
int mul(ll a, ll b) {
return a * b % mod;
}
//============didnt understand this step
int bin(int a, int d) {
int b = 1;
while (d) {
if (d & 1)
b = mul(b, a);
d >>= 1;
a = mul(a, a);
}
return b;
}
int rev(int a) {
assert(a != 0);
return bin(a, mod - 2);
}
const int maxn = 100100;
int px[maxn];
int c[maxn];
struct Fenwick {
int a[maxn];
int t[maxn];
void set(int pos, int val) {
int delta = add(val, mod - a[pos]);
a[pos] = val;
delta = mul(delta, px[pos]);
for (int i = pos; i < maxn; i |= i + 1) {
udd(t[i], delta);
}
}
int get(int r) {
int res = 0;
for (int i = r - 1; i >= 0; i = (i & (i + 1)) - 1)
udd(res, t[i]);
return res;
}
int get(int l, int r) {
return add(get(r), mod - get(l));
}
} fw;
int main() {
#ifdef LOCAL
assert(freopen("test.in", "r", stdin));
#endif
int n, a, b, q;
cin >> n >> a >> b >> q;
//========what does this line do?
int x0 = mul(mod - b, rev(a));
px[0] = 1;
for (int i = 1; i < n; ++i)
px[i] = mul(px[i - 1], x0);
forn (i, n) {
cin >> c[i];
fw.set(i, c[i]);
}
forn (i, q) {
int t, a, b;
cin >> t >> a >> b;
if (t == 1) {
fw.set(a, b);
} else {
++b;
int s = fw.get(a, b);
if (x0 == 0)
s = fw.a[a];
cout << (s == 0 ? "Yes" : "No") << '\n';
}
}
}
bin is the halving-and-squaring implementation for the (in this case modular) power function a^d % mod, so that the modular inverse in rev can be computed via the little theorem of Fermat.

Unable to find a wrong answer testcase for spoj MMINPAID

Problem link : http://www.spoj.com/problems/MMINPAID/
Getting WA on submitting.
I have used bfs to reach Nth node and calculating minimum cost for nodes in a path using bitmask. However after running on a huge number of testcases and comparing with an accepted solution, not able to find a failure testcase.
Code:
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int MAXN = 15, INF = 1 << 29;
struct node {
int c, p, r;
};
struct node data[MAXN][MAXN];
vector<int> g[MAXN];
int N, M, dist[MAXN][1 << 11];
int bfs() {
for (int i = 0; i < MAXN; i++)
for (int k = 0; k < (1 << 11); k++)
dist[i][k] = INF;
queue< pair< pair <int, int> , int > > q;
int v = 1, path = (1 << 1), cost = 0;
dist[v][path] = 0;
q.push(make_pair(make_pair(v, path), cost));
while (!q.empty()) {
int curv = q.front().first.first;
int curpath = q.front().first.second;
int curcost = q.front().second;
q.pop();
for (int i = 0; i < g[curv].size(); i++) {
int nv = g[curv][i];
int d1 = curcost + data[curv][nv].r;
int d2 = INF;
if (curpath & (1 << data[curv][nv].c)) {
d2 = curcost + data[curv][nv].p;
}
int d3 = min(d1, d2);
int npath = curpath | (1 << nv);
if (d3 < dist[nv][npath]) {
dist[nv][npath] = d3;
q.push(make_pair(make_pair(nv, npath), d3));
}
}
}
int res = INF;
for (int i = 0; i < (1 << 11); i++) {
res = min(res, dist[N][i]);
}
return res;
}
int main() {
scanf("%d %d", &N, &M);
for (int i = 0; i < M; i++) {
int a, b, c, p, r;
scanf("%d %d %d %d %d", &a, &b, &c, &p, &r);
g[a].push_back(b);
data[a][b] = (struct node) {c, p, r};
}
int ret = bfs();
if (ret == INF) printf("impossible\n");
else printf("%d\n", ret);
return 0;
}
I think the problem might be that your data[a][b] structure assumes there is at most a single road from a to b.
However, the problem states:
There may be more than one road connecting one city with another.

Finding bridges in graph without recursion

I have this code to find bridges in a connected graph:
void dfs (int v, int p = -1) {
used[v] = true;
tin[v] = fup[v] = timer++;
for (size_t i=0; i<g[v].size(); ++i) {
int to = g[v][i];
if (to == p) continue;
if (used[to])
fup[v] = min (fup[v], tin[to]);
else {
dfs (to, v);
fup[v] = min (fup[v], fup[to]);
if (fup[to] > tin[v])
printf("%d %d", v, to);
}
}
}
How to rewrite it without using recursion? I know, it's possible to do it and I should use stack, but this line must be executed after recursive call of dfs() and I can't achieve with a stack:
fup[v] = min(fup[v], fup[to])
So, how to rewrite my algorithm iteratively?
You want to make a "stack frame" structure
struct Frame {
Frame(int v, int p, int i, Label label);
int v;
int p;
int i;
};
// constructor here
and, as you say, a stack<Frame>. Between all of these fields, it's possible to simulate the call stack (untested code to give the general idea).
void dfs(int v, int p = -1) {
stack<Frame> st;
st.push(Frame(v, p, 0));
do {
Frame fr(st.top());
st.pop();
v = fr.v;
p = fr.p;
int i(fr.i);
if (i > 0) {
int to(g[v][i - 1]);
fup[v] = min(fup[v], fup[to]);
if (fup[to] > tin[v]) { printf("%d %d", v, to); }
if (i == g[v].size()) { continue; }
} else if (i == 0) {
used[v] = true;
tin[v] = fup[v] = timer++;
}
int to(g[v][i]);
if (to == p) { continue; }
if (used[to]) {
fup[v] = min(fup[v], tin[to]);
} else {
st.push(Frame(to, v, 0));
}
st.push(Frame(v, p, i + 1));
} while (!st.empty());
}
Sorry for the late reply.
Change code of previous answer and now it works fine.
Tested in contest task to find all bridges in connected Graph.
Hope it will help you.
// Copyright 2020 Kondratenko Evgeny
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
struct Frame {
Frame(int v, int p, int i) : v(v), p(p), i(i) {
}
int v;
int p;
int i;
};
void DFS(int n,
const std::vector<std::vector<int>> &G,
const std::vector<std::vector<int>> &weights) {
std::vector<bool> used(n + 1, false);
std::vector<int> ret(n + 1); // the same as tup
std::vector<int> enter(n + 1); // the same as tin
std::stack<Frame> s;
s.push(Frame(1, -1, 0));
int time = 1;
while (!s.empty()) {
Frame f = s.top();
s.pop();
int v = f.v;
int p = f.p;
int i = f.i;
if (i == 0) {
enter[v] = ret[v] = time++;
used[v] = true;
}
// First part works befor DFS call
if (i < G[v].size()) {
int to = G[v][i];
s.push(Frame(v, p, i + 1));
if (to != p) {
if (used[to]) {
ret[v] = std::min(ret[v], enter[to]);
} else {
s.push(Frame(to, v, 0));
}
}
}
/*
Generally here is virtual DFS recursive call, which we are simulate now
*/
// Second part after DFS call
if (i > 0 && i <= G[v].size()) {
int to = G[v][i - 1];
if (to != p) {
ret[v] = std::min(ret[v], ret[to]);
if (ret[to] > enter[v]) {
std::cout << "bridge between: " << v << " and " << to;
std::cout << ", with weight: " << weights[v][i - 1] << std::endl;
}
}
}
}
}
int main() {
int n, m; // n - number of vertex, m - number of edges
std::cin >> n >> m;
std::vector<std::vector<int>> G(n + 1, std::vector<int>()); // your Graph
std::vector<std::vector<int>> weights(n + 1, std::vector<int>());
for (int i = 0; i < m; ++i) { // read edges with weigths
int u, v, w;
std::cin >> u >> v >> w;
G[u].push_back(v);
G[v].push_back(u);
weights[u].push_back(w);
weights[v].push_back(w);
}
DFS(n, G, weights);
return 0;
}

High score in grid walk

There is an interesting game named one person game. It is played on a m*n grid. There is an non-negative integer in each grid cell. You start with a score of 0. You cannot enter a cell with an integer 0 in it. You can start and end the game at any cell you want (of course the number in the cell cannot be 0). At each step you can go up, down, left and right to the adjacent grid cell. The score you can get at last is the sum of the numbers on your path. But you can enter each cell at most once.
The aim of the game is to get your score as high as possible.
Input:
The first line of input is an integer T the number of test cases. The first line of each test case is a single line containing 2 integers m and n which is the number of rows and columns in the grid. Each of next the m lines contains n space-separated integers D indicating the number in the corresponding cell
Output:
For each test case output an integer in a single line which is maximum score you can get at last.
Constraints:
T is less than 7.
D is less than 60001.
m and n are less than 8.
Sample Input:
4
1 1
5911
1 2
10832 0
1 1
0
4 1
0
8955
0
11493
Sample Output:
5911
10832
0
11493
I tried it but my approach is working very slow for a 7x7 grid.I am trying to access every possible path of the grid recursively and comparing the sum of every path.Below is my code
#include<iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;
int max(int a,int b,int c, int d)
{
int max = a;
if(b>max)
max = b;
if(c>max)
max = c;
if(d>max)
max = d;
return max;
}
int Visit_Component( int (*A)[8], int Visit[8][8], int m,int n , int row, int col)
{
if ( ( row >= m ) || (col >= n ) || (col < 0) || (row < 0) || A[row][col] == 0 || Visit[row][col] == 1 )
{
return 0;
}
else
{
Visit[row][col] = 1;
int a= 0,b=0,c=0,d=0,result =0;
a = Visit_Component( A, Visit,m,n, row+1, col);
b = Visit_Component( A, Visit,m,n, row, col +1);
c = Visit_Component( A, Visit,m,n, row, col -1);
d = Visit_Component( A, Visit,m,n, row-1, col );
Visit[row][col] = 0;
result = A[row][col] + max(a,b,c,d);
return result;
}
}
int main(){
int T;
scanf("%d",&T);
for(int k =0; k<T;k++)
{
int N ;
int M;
int count = 0;
int maxcount = 0;
scanf("%d %d",&M,&N);
int C[8][8];
int visit[8][8];
for(int i = 0; i < M; i++)
for(int j = 0; j < N; j++)
{
scanf("%d",&C[i][j]);
visit[i][j] = 0;
}
for( int i= 0 ; i< M ; i++ )
{
for( int j =0; j< N ; j++ )
{
count = Visit_Component( C, visit,M,N, i, j);
if(count > maxcount)
{
maxcount = count;
}
}
}
printf("%d\n",maxcount);
}
return 0;
}
Please suggest me how to optimize this approach or a better algorithm.
As Wikipedia article on Travelling salesman problem suggests, there are exact algorithms, solving this task quickly. But it is hard to find any. And they are, most likely, complicated.
As for optimizing OP's approach, there are several possibilities.
It's easier to start with simple micro-optimization: condition Visit[row][col] == 1 is satisfied with highest probability, so it should come first.
Also it is reasonable to optimize branch-and-bound algorithm with dynamic programming to avoid some repeated calculations. Memorizing calculation results in simple hash table for the cases of up to 19 visited cells improves performance by more than 25% (and more may be expected for some improved hash table). Here is the modified code snippet:
#include<iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;
int max(int a,int b,int c, int d)
{
int max = a;
if(b>max)
max = b;
if(c>max)
max = c;
if(d>max)
max = d;
return max;
}
typedef unsigned long long ull;
static const int HS = 10000019;
static const int HL = 20;
struct HT {
ull v;
int r;
int c;
};
HT ht[HS] = {0};
int Visit_Component(
int (*A)[8], ull& Visit, int m,int n , int row, int col, int x)
{
if ( (Visit & (1ull << (8*row+col))) || ( row >= m ) || (col >= n ) ||
(col < 0) || (row < 0) || A[row][col] == 0)
{
return 0;
}
else
{
if (x < HL)
{
HT& h = ht[(Visit+4*row+col)%HS];
if (h.v == Visit && h.r == row && h.c == col)
return 0;
}
Visit |= (1ull << (8*row+col));
int a= 0,b=0,c=0,d=0,result =0;
a = Visit_Component( A, Visit,m,n, row+1, col, x+1);
b = Visit_Component( A, Visit,m,n, row, col +1, x+1);
c = Visit_Component( A, Visit,m,n, row, col -1, x+1);
d = Visit_Component( A, Visit,m,n, row-1, col , x+1);
Visit &= ~(1ull << (8*row+col));
result = A[row][col] + max(a,b,c,d);
if (x < HL)
{
HT& h = ht[(Visit+4*row+col)%HS];
h.v = Visit;
h.r = row;
h.c = col;
}
return result;
}
}
int main(){
int T;
scanf("%d",&T);
for(int k =0; k<T;k++)
{
int N ;
int M;
int count = 0;
int maxcount = 0;
scanf("%d %d",&M,&N);
int C[8][8];
ull visit = 0;
for(int i = 0; i < M; i++)
for(int j = 0; j < N; j++)
{
scanf("%d",&C[i][j]);
}
for( int i= 0 ; i< M ; i++ )
{
for( int j =0; j< N ; j++ )
{
count = Visit_Component( C, visit,M,N, i, j, 0);
if(count > maxcount)
{
maxcount = count;
}
}
}
printf("%d\n",maxcount);
}
return 0;
}
And much more improvements may be done by pre-processing the input matrix. If there are no zeros in the matrix or if there is only one zero in the corner, you may just sum all the values.
If there is only one zero value (not in the corner), at most one non-zero value should be excluded from the sum. If you invent an algorithm, that determines the subset of cells, from which one of the cells must be removed, you can just select the smallest value from this subset.
If there are two or more zero values, use branch-and-bound algorithm: in this case it is about 20 times faster, because each zero value in input matrix means approximately fivefold speed increase.
One optimization that I can think of is to apply Dijkstra's algorithm. This algorithm will give you a minimum (in your case maximum) path for a particular source node to all destination nodes.
In this example, the first step would be to build a graph.
And because you don't know the source node to start at, you will have to apply Dijkstra's algorithm for each node in the grid. The time complexity will be better than your recursion method because for a particular source node, when finding a maximum path Dijkstra's algorithm does not go through all the possible paths.
#include<iostream>
#include<vector>
using namespace std;
vector<vector<int> >A;
vector<vector<bool> >test;
vector<vector<bool> >test1;
int sum_max=0;
int m,n;
vector<vector<bool> > stamp;
void color1(int i,int j,vector<vector<bool> >temp_vector,vector<vector<bool> > st,int summ){
temp_vector[i][j]=false;summ+=A[i][j];st[i][j]=true;
//1.1
if(i+1<m && temp_vector[i+1][j]){
if(test1[i+1][j]){
if(sum_max<(summ)){sum_max=summ;stamp=st;}
}
else{color1(i+1,j,temp_vector,st,summ);}
}
//1.2
if(i+1<m){if(!temp_vector[i+1][j]){ if(sum_max<(summ)){sum_max=summ;}}}
if(i+1>=m){if(sum_max<(summ)){sum_max=summ;}}
//2
if(i-1>=0 && temp_vector[i-1][j]){
if(test1[i-1][j]){
if(sum_max<(summ)){sum_max=summ;}
}
else{ color1(i-1,j,temp_vector,st,summ);}
}
//2.2
if(i-1>=0){if(!temp_vector[i-1][j]){ if(sum_max<(summ)){sum_max=summ;}}}
if(i-1<0){if(sum_max<(summ)){sum_max=summ;}}
//3
if(j+1<n && temp_vector[i][j+1]){
if(test1[i][j+1]){
if(sum_max<(summ)){sum_max=summ;}
}
else{ color1(i,j+1,temp_vector,st,summ);}}
//3.2
if(j+1<n){if(!temp_vector[i][j+1]){ if(sum_max<(summ)){sum_max=summ;}}}
if(j+1>=n){if(sum_max<(summ)){sum_max=summ;}}
//4
if(j-1>=0 && temp_vector[i][j-1]){
if(test1[i][j-1]){
if(sum_max<(summ)){sum_max=summ;}
}
else{ color1(i,j-1,temp_vector,st,summ);}}
//4.2
if(j-1>=0){if(!temp_vector[i][j-1]){ if(sum_max<(summ)){sum_max=summ;}}}
if(j+1<0){if(sum_max<(summ)){sum_max=summ;}}
}
void color(int i,int j){
test[i][j]=false;
if(i+1<m && test[i+1][j]){
color(i+1,j);}
if(i-1>=0 && test[i-1][j]){
color(i-1,j);
}
if(j+1<n && test[i][j+1]){
color(i,j+1);}
if(j-1>=0 && test[i][j-1]){color(i,j-1);}
}
int main(){
int tc;cin>>tc;
for(int i=0;i<tc;i++){
int mp,np;
cin>>mp;
cin>>np;m=mp;n=np;A.resize(m);test.resize(m);test1.resize(m);int sum=0;
vector<bool> ha1(m,1);
vector<bool> ha2(n,1);
for(int i=0;i<m;i++){A[i].resize(n);test[i].resize(n);test1[i].resize(n);
for(int j=0;j<n;j++){
cin>>A[i][j];sum+=A[i][j];
test[i][j]=true;test1[i][j]=false;
if(A[i][j]==0){test[i][j]=false;ha1[i]=false;ha2[j]=false;}
}
}cout<<endl;
for(int i=0;i<m;i++){cout<<" "<<ha1[i];} cout<<endl;
for(int i=0;i<n;i++){cout<<" "<<ha2[i];} cout<<endl;
cout<<"sum "<<sum<<"\n";
int temp_sum=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){//if(A[i][j]<=8845){cout<<"\nk "<<A[i][j]<<" "<<(8845-A[i][j]);}
if(test[i][j]){
if((i-1)>=0 && test[i-1][j] && (i+1)<m && test[i+1][j] && (j-1)>=0 && test[i][j-1] && (j+1)<n && test[i][j+1] && test[i-1][j-1] && test[i-1][j+1]&& test[i+1][j-1] && test[i+1][j+1]){
temp_sum+=A[i][j];test1[i][j]=true;}
}
// cout<<test1[i][j]<<" ";
}//cout<<"\n";
}
// /*
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(test1[i][j]){if(!((test1[i-1][j]||test1[i+1][j]) && (test1[i][j-1]||test1[i][j+1]))){
temp_sum-=A[i][j]; test1[i][j]=false;}
}
//
// cout<<test1[i][j]<<" ";
}//
// cout<<"\n";
}
// */
//cout<<"\n temp_sum is "<<temp_sum<<endl;
vector<vector<bool> > st(m,vector<bool>(n,0));st=test1;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(test[i][j] && (!test1[i][j])){
color1(i,j,test,st,0);
}}}
// cout<<"\nsum is "<<(sum_max+temp_sum)<<endl<<endl;
cout<<(sum_max+temp_sum)<<endl;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){cout<<stamp[i][j]<<" ";} cout<<endl;}
// cout<<max<<endl;
A.clear();
test.clear();
test1.clear();
sum_max=0;
}
cout<<endl;system("pause");
return 0;
}

Resources