Adjacent matrix - c++

How can I combine these two functions to create a program that will allow a user to enter the count of vertices and then enter the graph edges?
#include <iostream>
using namespace std;
int **malloc2d(int r, int c)
{
int **t = new int*[r];
for(int i = 0; i < r; i++)
t[i] = new int[c];
return t;
}
int main()
{
int i;
int j;
int adj[V][V];
for(i = 0; i < V; i++)
for(j = 0 ; j < V; j++)
adj[i][j] = 0;
for(i = 0; i < V; i++)
adj[i][i]= 1;
while (cin>> i >> j)
{
adj[i][j] = 1;
adj[j][i] = 1;
}
system("pause");
return 0;
}

You could use std::vector<std::vector<bool>> or boost::adjacency_matrix, it's simpler.
std::size_t v;
std::cin >> v;
std::vector<std::vector<bool>> g(v);
for(auto& elem: g)
elem.resize(v, false);
boost::adjacency_matrix<boost::undirectedS> ug(v);
std::size_t e;
std::cin >> e;
for(std::size_t i = 0; i < e; ++i)
{
std::size_t v1, v2;
std::cin >> v1 >> v2;
g.at(v1).at(v2) = true;
g.at(v2).at(v1) = true;
boost::add_edge(v1, v2, ug);
}

Related

Segmentation Fault while getting input from 2D vector

I get a segmentation fault when I run the code below.
int main()
{
int R, C, val;
cin>>R>>C;
vector<vector<int>> a;
for(int i = 0; i < R; i++)
{
for(int j = 0; j < C; j++)
{
cin>>val;
a[i].push_back(val);
}
}
But when I change it to this, it seems to work. What is the reason?
int main()
{
int R, C, val;
cin>>R>>C;
vector<vector<int>> a;
for(int i = 0; i < R; i++)
{
vector<int>temp;
for(int j = 0; j < C; j++)
{
cin>>val;
temp.push_back(val);
}
a.push_back(temp);
}
I get the same fault no matter what the value of R and C is kept.
You have never told what is the size of vector<vector<int>>, and you try to access a[i].
You have to resize the vector.
int main()
{
int R, C;
std::cin >> R >> C;
std::vector<std::vector<int>> a(R, std::vector<int>(C));
for(int i = 0; i < R; i++)
{
for(int j = 0; j < C; j++)
{
std::cin >> a[i][j]; //because we resize the vector, we can do this
}
}
}

The program compiles without error, but if I call a function there is no output

After the function is called, the main() function does not execute.
I implemented dijkstra's algorithm in C++, adding "cout<<"called main\n" to the first line of the main () function to see if the main function was properly called.But if I call the function dijkstra(mygragh g,int dis[],int pre[],int v0), the program would have no output, and "called main" can be output normally without using the function.Can anyone suggest why it would happend?
#include <iostream>
#include <vector>
using namespace std;
struct mygragh{
int map[1000][1000];
int e;
int n;
};
void dijkstra(mygragh g,int dis[],int pre[],int v0){
cout << "called dijkstra\n";
int n = g.n;
vector<bool> visit(n, false);
for (int i = 0; i < n;i++){
if(g.map[v0][i]!=INT_MAX){
dis[i] = g.map[v0][i];
pre[i] = v0;
}
else{
dis[i] = INT_MAX;
pre[i] = -1;
}
}
visit[v0]=true;
for(int i=0;i<n;i++){
int min = INT_MAX,u=-1;
for (int j = 0; j < n;j++){
if(visit[j]==false&&dis[j]<min){
min = dis[j];
u = j;
}
}
if(u==-1){
break;
}
visit[u] = true;
for (int j = 0; j < n;j++){
if(visit[j]==false&&dis[j]>dis[u]+g.map[u][j]){
dis[j] = dis[u] + g.map[u][j];
pre[j] = u;
}
}
}
}
int main(){
cout << "called main\n";
mygragh g;
int n = 5;
int e = 7;
g.n = n;
g.e = e;
int dis[n];
int pre[n];
for (int i = 0; i < n;i++){
for (int j = 0; j < n;j++){
g.map[i][j] = 100;
}
}
//fill(g.map, g.map + n * n, INT_MAX);
for (int i = 0; i < n;i++){
g.map[i][i] = 0;
}
for (int i = 0; i < e;i++){
int c1, c2, l;
cin >> c1 >> c2 >> l;
g.map[c1][c2] = l;
g.map[c2][c1] = l;
}
dijkstra(g, dis, pre, 0);
cout << dis[1];
return 0;
}

Isomorphic graph parallel code implementation using openmp

I am trying to implement a parallel code for graph isomorphism(checking if 2 graphs are isomorphic or not) using openmp. I have the sequential code below, written in C++ which works only for regular graphs.
I have taken the input from a text file (input.txt) which contains number of nodes and 2 adjacency matrices representing 2 graphs. The output.txt file indicates whether the graphs are isomorphic or NON isomorphic along with the execution time.
I have used is_regular() function to check if a graph is regular graph or not.
Can someone please help me parallelize this code using openmp.
#include <time.h>
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <string>
using namespace std;
bool is_regular(vector<string> &adj) {
int nv = adj.size();
int cnt = 0;
for (int j = 0; j < nv; ++j)
if (adj[0][j] == '1') ++cnt;
for (int i = 1; i < nv; ++i) {
int sch = 0;
for (int j = 0; j < nv; ++j)
if (adj[i][j] == '1') ++sch;
if (sch != cnt) return false;
}
return true;
}
vector<vector<int> > foo1(vector<string> &adj, char R) {
int nv = adj.size();
vector<vector<int> > res;
for (int v1 = 0; v1 < nv; ++v1) {
vector<int> tmp;
vector<bool> b(nv);
vector<int> p, q;
p.push_back(v1);
b[v1] = true;
while (!p.empty()) {
q.clear();
for (size_t i = 0; i < p.size(); ++i) {
for (int j = 0; j < nv; ++j)
{
if (!b[j] && adj[p[i]][j] == R) {
b[j] = true;
q.push_back(j);
}
}
}
if (q.empty()) break;
vector<int> d(p.size());
vector<int> e(q.size());
for (size_t i = 0; i < p.size(); ++i) {
for (size_t j = 0; j < q.size(); ++j) {
if (adj[p[i]][q[j]] == R) {++d[i]; --e[j];}
}
}
sort(d.begin(), d.end());
sort(e.begin(), e.end());
copy(d.begin(), d.end(), back_inserter(tmp));
copy(e.begin(), e.end(), back_inserter(tmp));
p.swap(q);
}
res.push_back(tmp);
}
sort(res.begin(), res.end());
return res;
}
vector<vector<int> > foo2(vector<string> &adj, char R) {
int nv = adj.size();
vector<vector<int> > res;
for (int v1 = 0; v1 < nv; ++v1) {
for (int v2 = v1 + 1; v2 < nv; ++v2) {
vector<int> tmp;
vector<bool> b(nv);
vector<int> p, q;
p.push_back(v1);
p.push_back(v2);
b[v1] = true;
b[v2] = true;
while (!p.empty()) {
q.clear();
for (size_t i = 0; i < p.size(); ++i) {
for (int j = 0; j < nv; ++j) {
if (!b[j] && adj[p[i]][j] == R) {
b[j] = true;
q.push_back(j);
}
}
}
if (q.empty()) break;
vector<int> d(p.size());
vector<int> e(q.size());
for (size_t i = 0; i < p.size(); ++i) {
for (size_t j = 0; j < q.size(); ++j) {
if (adj[p[i]][q[j]] == R) {++d[i]; --e[j];}
}
}
sort(d.begin(), d.end());
sort(e.begin(), e.end());
copy(d.begin(), d.end(), back_inserter(tmp));
copy(e.begin(), e.end(), back_inserter(tmp));
p.swap(q);
}
res.push_back(tmp);
}
}
sort(res.begin(), res.end());
return res;
}
vector<vector<int> > foo3(vector<string> &adj, char R) {
int nv = adj.size();
vector<vector<int> > res;
for (int v1 = 0; v1 < nv; ++v1) {
for (int v2 = v1 + 1; v2 < nv; ++v2) {
for (int v3 = v2 + 1; v3 < nv; ++v3) {
vector<int> tmp;
vector<bool> b(nv);
vector<int> p, q;
p.push_back(v1);
p.push_back(v2);
p.push_back(v3);
b[v1] = true;
b[v2] = true;
b[v3] = true;
while (!p.empty()) {
q.clear();
for (size_t i = 0; i < p.size(); ++i) {
for (int j = 0; j < nv; ++j) {
if (!b[j] && adj[p[i]][j] == R) {
b[j] = true;
q.push_back(j);
}
}
}
if (q.empty()) break;
vector<int> d(p.size());
vector<int> e(q.size());
for (size_t i = 0; i < p.size(); ++i) {
for (size_t j = 0; j < q.size(); ++j) {
if (adj[p[i]][q[j]] == R) {++d[i]; --e[j];}
}
}
sort(d.begin(), d.end());
sort(e.begin(), e.end());
copy(d.begin(), d.end(), back_inserter(tmp));
copy(e.begin(), e.end(), back_inserter(tmp));
p.swap(q);
}
res.push_back(tmp);
}
}
}
sort(res.begin(), res.end());
return res;
}
int main() {
int nt = 1;
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n;
int tc = 0;
while (cin >> n) {
vector<string> adj1(n);
vector<string> adj2(n);
for (int i = 0; i < n; ++i) cin >> adj1[i];
for (int i = 0; i < n; ++i) cin >> adj2[i];
clock_t start = clock();
string answer = "NON-isomorphic";
if (!is_regular(adj1) || !is_regular(adj2)) {
answer = "Non regular graph";
goto mmm;
}
if (foo1(adj1,'1') != foo1(adj2,'1') || foo1(adj1,'0') != foo1(adj2,'0')) {
answer += " * ";
goto mmm;
}
if (foo2(adj1,'1') != foo2(adj2,'1') || foo2(adj1,'0') != foo2(adj2,'0')) {
answer += " ** ";
goto mmm;
}
if (foo3(adj1,'1') != foo3(adj2,'1') || foo3(adj1,'0') != foo3(adj2,'0')) {
answer += " ***";
goto mmm;
}
answer = "isomorphic";
mmm:
++tc;
printf("%d) n = %d %s", tc, n, answer.c_str());
printf(" %f\n", (double)(clock() - start) / CLOCKS_PER_SEC);
}
return 0;
}

Having trouble implementing pseudocode for Subset Sum

so I am trying to implement the following pseudocode but it will not work as it is supposed to. Here is the problem description in the slide, "Given an integer bound, "W", and a collection of "n" items, each with a positive integer weight "wi", find a subset S of items that: maximizes Sigma sub i where i is an element of S "wi" while keeping this sum less than or equal or to W. I will attach the following slides for where I am getting the problem description and pseudocode from. The problem with my implementation is that it will only find the total max value and not the value that is less than or equal to the weight. So for example, if I had Weight 10 (W = 10) and items 3 (n = 3) with item weights 1, 4, & 8 then the following answer should be 9; however, my solution gives 12. Here are the slides (*Please not, where it says w[j] it is meant to be w[i] - the slide had a typo):
Here is my code that implements the pseudocode:
#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int max(int a, int b, int c) {
if (a >= b)
return a;
else
return b;
}
int optimal_weight(int W, const vector<int> &wt, int n){
vector<vector<int> > M;
M.resize(n+1);
for(int i = 0; i < n+1; ++i){
M[i].resize(W+1);
}
for(int w = 0; w < W+1; w++){
M[0][w] = 0;
}
for(int i = 1; i < n+1; i++){
M[i][0] = 0;
}
for(int i = 1; i < n+1; i++){
for(int w = 0; w < W+1; w++){
if(wt[i] > w){
M[i][w] = M[i-1][w];
}
M[i][w] = max(M[i-1][w], wt[i] + M[i-1][W-wt[i]], W);
}
}
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= W; j++)
printf ("%4d", M[i][j]);
printf("\n");
}
return M[n][W];
}
int main()
{
//int val[] = {1, 1, 1};
int W;
int n;
cin >> W >> n;
vector<int> wt(n);
for(int i = 0; i < n; i++){
cin >> wt[i];
}
cout << optimal_weight(W, wt, n) << endl;
}
Thank you for any help!
I figured it out! Here is my solution:
#include <iostream>
#include <vector>
using namespace std;
using std::vector;
int optimal_weight(int W, const vector<int> &wt) {
//write your code here
int n = wt.size();
vector<vector<int> > matrix;
matrix.resize(W+1);
for(int i = 0; i < W+1; i++){
matrix[i].resize(n);
}
for(int j = 0; j < n; j++){
matrix[0][j] = 0;
}
for(int w = 0; w < W + 1; w++){
matrix[w][0] = 0;
}
for(int i = 1; i < n; i++){
for(int w = 1; w < W+1; w++){
matrix[w][i] = matrix[w][i-1];
if(wt[i] <= w){
//cout << wt[i] << endl;
int val = matrix[w-wt[i]][i-1] + wt[i];
if(matrix[w][i] < val){
matrix[w][i] = val;
}
}
}
}
return matrix[W][n-1];
}
int main() {
int n, W;
std::cin >> W >> n;
vector<int> wt(n+1);
for (int i = 1; i < n+1; i++) {
wt[0]=0;
std::cin >> wt[i];
}
std::cout << optimal_weight(W, wt) << '\n';
}

Kosaraju's Algorithm for spoj's BOTTOM

I am trying to solve http://www.spoj.com/problems/BOTTOM/
Here are the steps I am following:
1) Find the strongly connected components using Kosaraju's algorithm. 2) Consider a strongly connected component. Consider an edge u. Now consider all edges from u to some vertice v. If v lies in some other SCC, eliminate the whole strongly conected component. Else include all the elements in the solution.
However, I am constantly getting WA. Please help.
Here is my code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <fstream>
#include <iterator>
#include <queue>
using namespace std;
int k = 0;
int V, E;
bool fix[5001];
bool fix2[5001];
int compNum[5001];
void dfs(int v, vector< vector<int> >&G, bool *fix, vector <int> &out) {
fix[v] = true;
for (int i = 0; i < G[v].size(); i++) {
int u = G[v][i];
if (!fix[u]) {
fix[u] = true;
dfs(u, G, fix, out);
}
}
out.push_back(v);
}
void dfs2(int v, vector< vector<int> >&G, bool *fix2, vector < vector<int> > &components) {
fix2[v] = true;
for (int i = 0; i < G[v].size(); i++) {
int u = G[v][i];
if (!fix2[u]) {
fix2[u] = true;
dfs2(u, G, fix2, components);
}
}
components[k].push_back(v);
compNum[v] = k;
}
int main() {
int a, b;
while (true) {
cin >> V; if (V == 0) break; cin >> E;
vector< vector<int> >G(V + 1);
vector< vector<int> >G2(V + 1);
vector<int>out;
vector < vector<int> >components(V + 1);
for (int i = 0; i < E; i++) {
cin >> a >> b;
G[a].push_back(b);
G2[b].push_back(a);
}
for (int i = 1; i <= V; i++) {
if (!fix[i])
dfs(i, G, fix, out);
}
reverse(out.begin(), out.end());
for (int i = 0; i < out.size(); i++){
if (!fix2[out[i]]) {
dfs2(out[i], G2, fix2, components);
k++;
}
}
vector<int>gamotana;
for (int i = 0; i < components.size(); i++) {
for (int j = 0; j < components[i].size(); j++) {
bool check = true;
for (int z = 0; z < G[components[i][j]].size(); z++)
{
if (compNum[G[components[i][j]][z]] != i)
{
check = false; goto next123;
}
}
if (check)
gamotana.push_back(components[i][j]);
}
next123:;
}
sort(gamotana.begin(), gamotana.end());
for (int i = 0; i < gamotana.size(); i++)
cout << gamotana[i] << " ";
for (int i = 0; i < 5001; i++) {
fix[i] = false;
fix2[i] = false;
compNum[i] = -1;
}
k = 0;
cout << endl;
}
return 0;
}
In your algorithm description you say you eliminate the entire connected component if some edge leads to a different component.
However, in your code you appear to add all vertices j in component i to your solution until you find an edge leading out. In other words, even if a component is not a sink you may still incorrectly report some of the vertices as being sinks.
I imagine you should do something more like this:
for (int i = 0; i < components.size(); i++) {
for (int j = 0; j < components[i].size(); j++) {
for (int z = 0; z < G[components[i][j]].size(); z++)
{
if (compNum[G[components[i][j]][z]] != i)
{
goto next123;
}
}
}
for (int j = 0; j < components[i].size(); j++)
gamotana.push_back(components[i][j]);
next123:;
}
Of course, there may be more issues. I would recommend you try constructing and testing some small examples first, and perhaps testing against a brute force solver to identify failing cases.
#include<bits/stdc++.h>
using namespace std;
void dfs(vector<int>* edges, stack<int>& finishedVertices, bool* visited, int n, int start){
visited[start] = true;
for(int i = 0 ; i < edges[start].size() ; i++){
int node = edges[start][i];
if(!visited[node]){
dfs(edges, finishedVertices, visited, n, node);
}
}
finishedVertices.push(start);
}
void dfs_reverse(vector<int>* edgesT, bool* visited, unordered_map<int,vector<int>>& SCC, int node, int k){
SCC[k].push_back(node);
visited[node] = true;
for(int i = 0 ; i < edgesT[node].size() ; i++){
int new_node = edgesT[node][i];
if(!visited[new_node]){
dfs_reverse(edgesT, visited, SCC, new_node, k);
}
}
}
void getSCC(vector<int>* edges, vector<int>* edgesT, int n){
bool* visited = new bool[n];
for(int i = 0 ; i < n ; i++){
visited[i] = false;
}
stack<int> finishedVertices;
for(int i = 0 ; i < n ; i++){
if(!visited[i]){
dfs(edges, finishedVertices, visited, n, i);
}
}
unordered_map<int,vector<int>> SCC;
int k = 0;
for(int i = 0 ; i < n ; i++){
visited[i] = false;
}
while(!finishedVertices.empty()){
int node = finishedVertices.top();
finishedVertices.pop();
if(!visited[node]){
dfs_reverse(edgesT, visited, SCC, node, k);
k++;
}
}
int flag = 1;
vector<int> ans;
vector<int> bottom;
for(int i = 0 ; i < k ; i++){
for(int j = 0 ; j < SCC[i].size(); j++){
ans.push_back(SCC[i][j]);
}
for(int m = 0 ; m < ans.size() ; m++){
int node = ans[m];
for(int j = 0 ; j < edges[node].size() ; j++){
int new_node = edges[node][j];
vector<int> :: iterator it;
it = find(ans.begin(), ans.end(), new_node);
if(it == ans.end()){
flag = 0;
break;
}
}
if(flag == 0)
break;
}
if(flag == 1){
for(int j = 0 ; j < ans.size() ; j++)
bottom.push_back(ans[j]);
}
flag = 1;
ans.clear();
}
sort(bottom.begin(), bottom.end());
for(int i = 0 ; i < bottom.size() ; i++)
cout << bottom[i] + 1 << " ";
cout << endl;
}
int main(){
while(true){
int n;
cin >> n;
if(n == 0)
break;
vector<int>* edges = new vector<int>[n];
vector<int>* edgesT = new vector<int>[n];
int e;
cin >> e;
for(int i = 0 ; i < e ; i++){
int x, y;
cin >> x >> y;
edges[x-1].push_back(y-1);
edgesT[y-1].push_back(x-1);
}
getSCC(edges, edgesT, n);
delete [] edges;
delete [] edgesT;
}
return 0;
}