I have written the following code for the above problem.
I have checked if Graph is connected by choosing the start node and doing DFS from it. And checking the conditions for Euler path and tour, in code that would be count= 2 or 0. It's working on all given test cases.But getting wrong answer on submission
#include<iostream>
#include<cmath>
#include<list>
#include<string>
#include<stack>
using namespace std;
class Graph
{
int V;
list<int> *adj;
int *in;
public:
Graph(int v)
{
this->V=v;
this->adj=new list<int>[V];
this->in=new int[V];
for(int i=0;i<V;i++)
{
in[i]=0;
}
}
void addEdge(int src,int des)
{
adj[src].push_back(des);
in[des]=in[des]+1;
}
void DFSUtil(bool visited[],int v)
{
stack<int> s;
s.push(v);
visited[v]=true; //mark v as visited;
while (!s.empty())
{
int top=s.top();
s.pop();
list<int> :: iterator it;
for(it=adj[top].begin();it!=adj[top].end();it++)
{
if(!visited[*it])
{
visited[*it]=true;
s.push(*it);
}
}
}
}
/*void DFSUtil(bool visited[],int v)
{
visited[v]=true;
list<int> :: iterator it;
for(it=adj[v].begin();it!=adj[v].end();it++)
{
if(!visited[*it])
{
DFSUtil(visited,*it);
}
}
}*/
// Graph reverseGraph()
// {
// Graph g(V);
// for(int i=0;i<V;i++)
// {
// list<int> :: iterator it;
// for(it=adj[i].begin();it!=adj[i].end();it++)
// {
// g.addEdge(*it,i);
// }
// }
// return g;
// }
bool isConnected()
{
//bool visited[V];
bool* visited=new bool[V];
for(int i=0;i<V;i++)
visited[i]=false;
int i=0;
int flag=0;
int n;
for(i=0;i<V;i++)
{
if(adj[i].size()>0)
{
n=i;
flag=1;
}
if(((int)adj[i].size()-in[i])==1 && in[i]==0) //selecting the start vertex i.e vertex with no incoming edges
{
n=i;
break;
}
}
if(i==V&&flag==0)
return 0;
DFSUtil(visited,n); //dfs to check if every node is reachable fro start vertex
for(int i=0;i<V;i++)
{
if(visited[i]==false && adj[i].size()>0)
return 0;
}
// Graph gr=reverseGraph();
// for(int i=0;i<V;i++)
// visited[i]=false;
// gr.DFSUtil(visited,n);
// for(int i=0;i<V;i++)
// {
// if(visited[i]==false && adj[i].size()>0)
// return 0;
// }
return 1;
}
bool isEuler()
{
int count=0;
int magnitude;
for(int i=0;i<V;i++) //check conditions on in and out edges, out edges=adj[].size
{
magnitude=in[i]-(int)adj[i].size();
if(magnitude<0)
magnitude=magnitude*-1;
if((magnitude)==1)
{
count=count+1;
}
else if(in[i]!=adj[i].size())
{
return 0;
}
}
if(count==1 || count>2)
return 0;
if(isConnected()==0) //check if graph is connected
return 0;
return 1;
}
};
int main()
{
int t;
//scanf("%d",&t);
cin>>t;
while(t--)
{
int n;
//scanf("%d",&n);
cin>>n;
string str;
if(n==1) //only one string entered
{
cin>>str;
cout<<"Ordering is possible.\n";
continue;
}
Graph g(26);
int src,des;
for(int i=0;i<n;i++)
{
cin>>str;
src=str[0]-'a';
des=str[str.length()-1]-'a';
g.addEdge(src,des);
}
if(g.isEuler())
{
cout<<"Ordering is possible.\n";
}
else
{
cout<<"The door cannot be opened.\n";
}
}
}
In your function isConnected, you attempt to find the start vertex with no incoming edges by breaking out of the for loop upon a certain condition. If this condition is not encountered, the loop variable i will contain the value 26, rather than an expected index in the range 0..25. When the value 26 is passed to the DFSUtil function it will caused an out of bounds array access. I get a crash on the line visited[v] = true;
A condition that will cause this to arise, is the test case from the linked site with the repeated word:
2
ok
ok
Your check to find the start vertex does not handle this case well.
Related
I have implemented the Weighted graph along with BFS and DFS. But I cannot figure a way out how to stop the traversal when a destination node (specified by user) is reached. Like user should enter the src and dest, and the BFS and DFS algorithm should print the tree until that specified node is reached. I have tried some things but I just cannot understand how to do this. I am attaching the code, any help would be appreciated.
#include "iostream"
#include "vector"
#include "queue"
#include "stack"
using namespace std;
typedef pair<int , int> Pair;
struct Edge{
int src, dest, weight;
};
class Graph{
public:
vector<vector<Pair>> adjacencyList;
Graph(vector<Edge> const &edges, int N)
{
adjacencyList.resize(N);
for(auto &edge: edges)
{
int src = edge.src;
int dest = edge.dest;
int weight = edge.weight;
adjacencyList[src].push_back(make_pair(dest,weight));
adjacencyList[dest].push_back(make_pair(src,weight));
}
}
};
void BFS(Graph const &graph, int src, vector<bool> &discovered)
{
queue<int> q;
discovered[src] = true;
q.push(src);
while(!q.empty())
{
src = q.front();
q.pop();
cout<<src<<" ";
for(int i = 0; i != graph.adjacencyList[src].size() ;i++)
{
if(!discovered[i])
{
discovered[i] = true;
q.push(i);
}
}
}
}
void DFS(Graph const &graph, int src, vector<bool> &discovered)
{
stack<int> stack;
stack.push(src);
while(!stack.empty()){
src = stack.top();
stack.pop();
if(discovered[src])
{
continue;
}
discovered[src] = true;
cout<<src<< " ";
for(int i = 0 ; i < graph.adjacencyList[src].size() ; i++)
{
if(!discovered[i])
{
stack.push(i);
}
}
}
}
void printGraph(Graph const &graph, int N)
{
for (int i = 0; i < N; ++i) {
for(Pair v: graph.adjacencyList[i])
{
cout<<"("<<i<<" , "<<v.first<<" , "<<v.second<<")";
}
cout<<endl;
}
}
int main()
{
vector<Edge> edges =
{
// `(x, y, w)` —> edge from `x` to `y` having weight `w`
{0,1}, {0,2}, {0,3},
{1, 2}, {2,4}, {3,3}, {4,4}
};
int N = 5;
Graph graph(edges,N);
// printGraph(graph,N);
vector<bool> discovered(N, false);
for(int i = 0; i<N; ++i)
{
if(!discovered[i])
{
BFS(graph, i, discovered);
}
}
cout<<endl;
vector<bool> discovered2(N, false);
for(int i = 0; i<N; i++)
{
if(!discovered2[i])
{
DFS(graph, i , discovered2);
}
}
cout<<endl;
printGraph(graph, N);
}
A recursive design makes this much simpler. here is the depth first version
// set stopNode global
......
bool cPathFinder::depthRecurse(int v)
{
// remember this node has been visted
visted[v] = true;
// is this the sop npde
if ( v == stopNode ) {
return true;
}
// look for new adjacent nodes
for (int w : myGraph.all_neighbors(v)) {
if (!visited[w])
{
// search from new node
if( depthRecurse(w) )
return true;
}
}
}
#include<bits/stdc++.h>
using namespace std;
void addEdge(vector<vector<int > >&adj,int u,int v)
{
adj[u].push_back(v);
}
bool DFS(vector<vector<int > >adj,int x,vector<bool>&visited,vector<bool>&recStack,stack<int>&s)
{
if(recStack[x])
{
return true;
}
if(visited[x])
{
return false; // the node is already visited and we didn't a cycle with this node
}
visited[x]=true;
recStack[x]=true;
s.push(x);
for(int i=0;i<adj[x].size();i++)
{
if(DFS(adj,adj[x][i],visited,recStack,s))
{
return true;
}
}
recStack[x]=false;
s.pop();
return false;
}
bool graphHasCycle(vector<vector<int > >adj)
{
vector<bool>visited(adj.size(),false);
vector<bool>recStack(adj.size(),false);
stack<int>s;
for(int i=0;i<adj.size();i++)
{
if(DFS(adj,i,visited,recStack,s))
{
while(!s.empty())
{
cout<<s.top()<<" ";
s.pop();
}
return true;
}
}
return false;
}
int main()
{
/*int n=3,e=3;
vector<vector<int > >adj(n,vector<int>());
addEdge(adj,0,1);
addEdge(adj,1,2);
addEdge(adj,2,0);*/
/*int n=3,e=3;
vector<vector<int > >adj(n,vector<int>());
addEdge(adj,0,1);
addEdge(adj,1,2);
addEdge(adj,0,2);*/
/*int n=4,e=4;
vector<vector<int > >adj(n,vector<int>());
addEdge(adj,0,1);
addEdge(adj,1,2);
addEdge(adj,2,3);
addEdge(adj,3,1);*/
/*int n=5,e=6;
vector<vector<int > >adj(n,vector<int>());
addEdge(adj,0,1);
addEdge(adj,1,2);
addEdge(adj,0,2);
addEdge(adj,0,3);
addEdge(adj,3,4);
addEdge(adj,4,0);*/
cout<<"Adjacency list:\n";
for(int i=0;i<adj.size();i++)
{
for(int j=0;j<adj[i].size();j++)
{
cout<<adj[i][j]<<" ";
}
cout<<endl;
}
cout<<"Cycles:\n";
if(graphHasCycle(adj))
{
cout<<"Graph has cycle";
}
else
{
cout<<"No cycle";
}
return 0;
}
Code source:'Detect cycle in directed graph' from GeeksForGeeks.
Im trying to modify this code to also print the cycles using this code,but it doesnt seem to work on all cases.
for example in the graph with edges 0->1,1->2,2->3,3->1,it would print the cycle as 3 2 1 0 but the actual cycle is 3 2 1.It also fails when two cycles originate from the same vertex.
Please help me correct the code to print the cycles correctly.
Link to the code in online ide:
https://ide.geeksforgeeks.org/ujCcvL77ii
I think before each DFS call, you need to re-initialize recStack to false as below:
for(int i=0;i<adj.size();i++)
{
vector<bool>recStack(adj.size(),false); //for each call we need an empty recStack
stack<int>s; //initialize a new stack too.
if(DFS(adj,i,visited,recStack,s))
It's my program to simplify Karnough map. I need to change it from SOP to POS for university project. I changed already signs from + to * and from * to +. All i have to do now is to make it read zero-s from text file instead of one's. i tried everything to solve that problem, but i have no idea. I have got two txt files, one with input and one with output. At this moment i need to put in input 0's instead of 1's and in the other side to, to make it work. Please help me, my life depends of that
#include <iostream>
#include <fstream>
#include <cmath>
#include <windows.h>
using namespace std;
//?????
int pow2(int n) // ??2?????,2^n
{
int result=1
;
while(n>0)
result*=2,n--;
return result;
}
int combination(int n,int r) // ?????C_n^r,? n! / ((n-r)!*(r)!)
{
int fm=1,fz=1;
for(int i=1;i<=r;i++,n--)
{
fm*=i;
fz*=n;
}
return fz/fm;
}
void d2b(int d,char* b,int n) // ???????,??????d???????????b?
{
for(n--;n>=0;n--)
{
b[n]='0'+d%2;
d/=2;
}
}
int ispair(char* a1,char* a2,int n) // ????????????????
{
int x,y=0;
for(int i=0;i<n;i++)
if(a1[i]!=a2[i])
x=i,y++;
if(y==1) return x;
else return-1;
}
bool issame(char* a1,char* a2,int n) // ????
{
for(int i=0;i<n;i++)
if(a1[i]!=a2[i])
return 0;
return 1;
}
int left1(char* a,int N) // ???????????,??????1,??????
{
for(int i=0;i<N;i++)
if(a[i]=='1')
return i;
return -1;
}
void copy(char* a1,char* a2,int n) // ??????
{
for(int i=0;i<n;i++)
a2[i]=a1[i];
}
bool isinside(int x,char* a,int n) // ???x????????a?
{
for(n--;n>=0;n--)
{
if(a[n]!='x' && a[n]!=(char)('0'+x%2))
return 0;
x/=2;
}
return 1;
}
void output(fstream& file,char* a,int n)
{
for(int i=0;i<n;i++)
{
if(i==0)file<<'(';
if(a[i]=='0'||a[i]=='1')
{
if(a[i]=='0') file<<'¬'<<(char)('a'+i);
if(a[i]=='1') file<<(char)('a'+i);
if(a[i+1]=='0'||a[i+1]=='1'||a[i+2]=='0'||a[i+2]=='1'||a[i+3]=='0'||a[i+3]=='1')
{
file<<'+';
}
else{
file<<')';
}
}
else{}
;
}
file<<'*';
}
int count(char* table,char* a,int n,int N) // ??,????????1???????????a?
{
int counter=0;
for(int i=0;i<N;i++)
{
if(table[i]!='1') continue;
if(isinside(i,a,n)) counter++;
}
return counter;
}
void clean(char* table,char* a,int n,int N) // ??????????????????1,???x
{
for(int j=0;j<N;j++)
if(isinside(j,a,n))
table[j]='x';
}
int main()
{
SetConsoleTitle("???-???????????");
system("color 06");
//????
fstream inputFile("input.txt",ios::in); //??????????input.txt
int valNum; //???
inputFile >> valNum; // ???????????
cout<<"\n ????????: "<<valNum;
cout<<"\n ?????????:\n";
int minTermLength=pow2(valNum); // ??????????2^valNum?
char* minTermExpression=new char[minTermLength]; // ???????????????
int lineOff = pow2(ceil(double(valNum)/2));
// ???????
if (inputFile.is_open())
{
for(int i=0;i<minTermLength;i++) // ?????
{
inputFile>>minTermExpression[i];
if(i%lineOff == 0&&(i!=0))
cout<<"\n";
cout<<"\t"<<minTermExpression[i];
}
inputFile.close();
}
// ??????
else{
cout<<"\n ??input.txt??,???????";
return 0;
}
// ?implication????????
char*** implication=new char**[valNum]; // ????
int nonZeroNum=1;
for(int i=0;i<minTermLength;i++)
if(minTermExpression[i]!='0') // ?????ON???DC?????????
nonZeroNum++;
for(int i=0;i<valNum;i++) // i-??,???????3?,i=0???????,i=1???,i=2???
{
if(pow2(i)>nonZeroNum)break;
int x=pow2(i-1)*combination(nonZeroNum,pow2(i));
implication[i]=new char*[x];
for(int j=0;j<x;j++)
implication[i][j]=new char[valNum];
}
//?????????
int* countNum=new int[valNum+1];
countNum[0]=0;
for(int i=0;i<minTermLength;i++)
if(minTermExpression[i]!='0') // ???0?
{
d2b(i,implication[0][countNum[0]],valNum); // ??????????implication[0]???
countNum[0]++;
}
int isOptimal=0;
while(countNum[isOptimal]>0) // ??????????
{
countNum[isOptimal+1]=0;
for(int i=0;i<countNum[isOptimal]-1;i++)
for(int j=i+1;j<countNum[isOptimal];j++)
{
int x=ispair(implication[isOptimal][i],implication[isOptimal][j],valNum); // ??????????
if(x==-1) continue;
copy(implication[isOptimal][i],implication[isOptimal+1][countNum[isOptimal+1]],valNum);// ???implication??
implication[isOptimal+1][countNum[isOptimal+1]][x]='x'; // ??????????,?????????x,???????????
countNum[isOptimal+1]++;
}
for(int i=0;i<countNum[isOptimal+1]-1;i++)
for(int j=i+1;j<countNum[isOptimal+1];j++)
if(issame(implication[isOptimal+1][i],implication[isOptimal+1][j],valNum)) // ??????
{
for(int k=j;k<countNum[isOptimal+1]-1;k++)
copy(implication[isOptimal+1][k+1],implication[isOptimal+1][k],valNum);
countNum[isOptimal+1]--;
}
isOptimal++;
}
isOptimal--;
//???????
fstream outputFile("output.txt",ios::out);
outputFile<<"F=";
while(left1(minTermExpression,minTermLength)>=0) //?minTermExpression???1
{
bool flag=0; // ???,????
for(int i=0;i<minTermLength&&flag==0;i++)
{
if(minTermExpression[i]!='1') continue;
int counter=0,recorder;
for(int j=0;j<countNum[isOptimal];j++)
if(isinside(i,implication[isOptimal][j],valNum))
counter++,recorder=j;
if(counter!=1) continue;
output(outputFile,implication[isOptimal][recorder],valNum);
clean(minTermExpression,implication[isOptimal][recorder],valNum,minTermLength);
flag=1;
}
if(flag==1) continue;
int termMaxInclude=0;
int recorder=0;
for(int i=0;i<countNum[isOptimal];i++) // ??????????,???????????1???,??????
if(count(minTermExpression,implication[isOptimal][i],valNum,minTermLength)>termMaxInclude)
termMaxInclude=count(minTermExpression,implication[isOptimal][i],valNum,minTermLength),recorder=i;
if(termMaxInclude==0) {isOptimal--; continue;}
output(outputFile,implication[isOptimal][recorder],valNum);
clean(minTermExpression,implication[isOptimal][recorder],valNum,minTermLength);
}
outputFile.close();
// ?????
outputFile.open("output.txt",ios::in);
char finalExpression[201];
outputFile.getline(finalExpression,200);
outputFile.close();
int termMaxInclude=0;
for(;finalExpression[termMaxInclude]!='\0';termMaxInclude++);
finalExpression[termMaxInclude-1]='\0';
outputFile.open("output.txt",ios::out);
outputFile<<finalExpression;
outputFile.close();
cout<<"\n??????????????";
cout<<"\n ??????,??????!";
cin.get();
return 0;
}
The zeros are simply those not in the ones list.
I want to traverse a graph using BFS algorithm and want to track the nodes by their level.
Here is my code.
#include<iostream>
#include<queue>
#include<vector>
#include<stdlib.h>
using namespace std;
int main()
{
int edges,a,b;
vector<int>nodes[1000];
cout<<"Enter the no of edges"<<endl;
cin>>edges;
for(int i=0; i<edges; i++)
{
cin>>a>>b;
nodes[a].push_back(b);
nodes[b].push_back(a);
}
cout<<endl;
queue<int> que;
//initially que is empty
bool visited[1000];
int level[1000];
// mark all the vertices as not visited
for(int i=0; i<1000; i++)
{
visited[i]=false;
}
int start;
cout<<"\nEnter the starting node"<<endl;
cin>>start;
//insert the starting node into the queue
que.push(start);
level[start]=1;
//mark the starting node as visited
visited[start]=true;
cout<<"\nBFS Traversal\n";
while(!que.empty())
{
//Dequeue a vertex from que and print it
int front = que.front();
cout<<front<<" ";
que.pop();
// get all adjacent vertices of the dequeued vertex s
// If an adjacent vertex has not been visited,
//then mark it as visited
// and enqueue it
for(vector<int>::iterator it=nodes[front].begin();
it!=nodes[front].end(); ++it)
{
if(visited[*it]==false)
{
visited[*it]=true;
que.push(*it);
}
}
// cout<<endl;
}
cout<<endl;
int Sz = sizeof(level)/sizeof(int);
/*for(int i=0;i<=edges;i++)
{
cout<<"Level of "<<i<<"is "<<level[10]<<endl;
}*/
return 0;
}
[please notice the commented out portion at the end of the code.I tried some ways but failed.I removed those tracking.Please help me updating the code.]
You can use this function to find the level of each node in the tree.
Complexity is O(n) since we are visiting each node once.
Best of Luck
#define ll long long int
ll level[100005],arr[100005];
vector <ll> adj[100005];
void bfs(ll s)
{
ll vis[100005];
memset(vis,false,sizeof vis);
queue <ll> q;
q.push(s);
level[s] = 1;
vis[s] = true;
while(!q.empty())
{
ll p = q.front();
//cout<<p<<endl;
q.pop();
vector <ll>::iterator it;
for(it=adj[p].begin();it!=adj[p].end();++it)
{
if(vis[*it] == false)
{
level[*it] = level[p] + 1;
q.push(*it);
vis[*it] = true;
}
}
}
}
I just learnt Dijkstra's algorithm and solved a few problems and I am trying to solve this http://codeforces.com/problemset/problem/20/C problem but I am getting Time limit Exceeded in a large test case, I want to know if my code can be further optimized in any way or if there is any other faster implementation of Dijkstra then let me know.
My code
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define vp vector<pii>
int p[100010],d[100010];
void printer(int current)
{
if(p[current]==-2)
{
printf("%d ",current);
return;
}
printer(p[current]);
printf("%d ",current);
}
class Prioritize
{
public:
int operator()(const pii &p1,const pii &p2)
{
return p1.second<p2.second;
}
};
int main()
{
priority_queue<pii, vp, Prioritize> Q;
int nv;
scanf("%d",&nv);
vp g[nv+1];
int ne,u,v,w;
scanf("%d",&ne);
for(int i=0;i<ne;i++)
{
scanf("%d %d %d",&u,&v,&w);
g[u].push_back(pii(v,w));
g[v].push_back(pii(u,w));
}
int source=1;
int size;
for(int i=1;i<=nv;i++)
{
d[i]=INT_MAX;
p[i]=-1;
}
d[source]=0;
p[source]=-2;//marker for source.
Q.push(pii(source,d[source]));
while(!Q.empty())
{
u=Q.top().first;
Q.pop();
size=g[u].size();
for(int i=0;i<size;i++)
{
v=g[u][i].first;
w=g[u][i].second;
if(d[v]>d[u]+w)
{
d[v]=d[u]+w;
p[v]=u;
Q.push(pii(v,d[v]));
}
}
}
/*for(int i=1;i<=nv;i++)
{
printf("Node %d and min weight = %d and parent = %d\n",i,d[i],p[i]);
}*/
if(p[nv]==-1)
{
printf("%d\n",-1);
return 0;
}
printer(nv);
return 0;
}
Your algorithm has complexity O(nm). I propose to add the following
Q.push(pii(source,d[source]));
while(!Q.empty())
{
u=Q.top().first;
int curD = Q.top().second; //this
if( curD > d[u]) continue; //and this
Q.pop();
size=g[u].size();
for(int i=0;i<size;i++)
{
After changes complexity will be O(mlogn). If you now russian you can read http://e-maxx.ru/algo/dijkstra_sparse