Problems in evaluating subgraphs of a graph - c++

Here is the question link.
Given an undirected graph. Density of a graph is |E|⁄|V|. Your task is to choose non-empty set of vertices V such that subgraph induced on V has maximal density and print this density. But if maximal density is strictly greater than 1, just print ">1".
Maximum number of vertices: 105
Maximum number of edges: 105
I just made a simple solution, but in this solution I can keep track of the whole graph, but how do I get the value of density for smaller subGraphs?
#include<iostream>
#include<vector>
using namespace std;
vector<int> adj[1000002]; // adjacency lists adj for storing graph edges
int node=0; // initializing for node value(vertices)
bool visited[100001]={false}; // keeps track of visited nodes(vertices)
int edge=-1;
int ans=-1;
int n; // keeps optimum value of no. of nodes
int e; // keeps optimum value of no. of edges
void dfs(int s)
{
node++;
edge++;
if(edge>0)
{
float dummy=(float)edge/(float)node;
if(dummy>ans)
{ans=dummy;
e=edge;
n=node;
}
}
visited[s]=true;
int t;
for(int i=0;i!=adj[s].size();i++)
{ t=adj[s][i];
if(visited[t]==false)
{
dfs(t);
}
}
}
int main()
{
long long v,ed,i,j,x,y;
cin>>v>>ed;
for(long long k=0;k<ed;k++)
{
cin>>x>>y;
adj[x].push_back(y);
adj[y].push_back(x);
}
if(ed>v)
cout<<">1"<<endl;
else{
for(i=1;i<=v;i++)
{
if(visited[i]==false)
{
node=0;
edge=-1;
dfs(i);
//cout<<e<<"/"<<n<<endl;
}
}
cout<<e<<"/"<<n<<endl;}
}

Follow these steps to get better result:
1.Do a dfs on each component to get the answer.
2.Avoid the floating point calculation you are doing and try all integer calculation.
3.No reason to use long long here with that range
Change the code to something like this should work:
#include<iostream>
#include<vector>
using namespace std;
vector<int> adj[1000002]; // adjacency lists adj for storing graph edges
int node=0; // initializing for node value(vertices)
bool visited[100001]={false}; // keeps track of visited nodes(vertices)
int edge=0;
void dfs(int s)
{
node++;
visited[s]=true;
int t;
edge+=adj[s].size();
for(int i=0;i!=adj[s].size();i++)
{
t=adj[s][i];
if(visited[t]==false)
{
dfs(t);
}
}
}
int main()
{
int v,ed,i,j,x,y;
cin>>v>>ed;
for(int k=0;k<ed;k++)
{
cin>>x>>y;
adj[x].push_back(y);
adj[y].push_back(x);
}
int mark[3]; mark[0]=mark[1]=mark[2]=0;
int mx_node=0;
for(i=1;i<=v;i++)
{
if(visited[i]==false)
{
node=0;
edge=0;
dfs(i);
edge/=2;
if(node>edge){
mark[0]=1;
mx_node=mx_node<node?node:mx_node;
}
else if(node==edge) mark[1]=1;
else mark[2]=1;
}
}
if(mark[2]) printf(">1\n");
else if(mark[1]) printf("1\n");
else printf("%d/%d\n",mx_node-1,mx_node);
}

Related

dijkstra algorithm print path skips some numbers and doesnt work with some

when iam printing path it works fine if the starting numbers are 2,4,6,if its a 5,it prints nothing and if its 1,3 it doesnt print the first number for e.g
start:2
end:3
path: 2 6 5 3
start:5
end:3
path:nothing
start:3
end:5
path:4,5
distance between points works just fine, i cant understand why some paths print correctly and other ones dont.
#include<iostream>
#include<fstream>
#include<climits> /*Used for INT_MAX*/
using namespace std;
#define V 6 /*It is the total no of verteices in the graph*/
int minimumDist(int dist[], bool Dset[]) /*A method to find the vertex with minimum distance which is not yet included in Dset*/
{
int min=INT_MAX,index; /*initialize min with the maximum possible value as infinity does not exist */
for(int v=0;v<V;v++)
{
if(Dset[v]==false && dist[v]<=min)
{
min=dist[v];
index=v;
}
}
return index;
}
void printPath(int parent[], int j)
{
// Base Case : If j is source
if (parent[j] == -1)
{
return;
}
printPath(parent, parent[j]);
printf("%d ", j+1);//+1 kad kazkas panasiau i veikima atrodytu
}
void dijkstra(int graph[V][V],int src,int n) /*Method to implement shortest path algorithm*/
{
int dist[V];
bool Dset[V];
int parent[V];
for(int i=0;i<V;i++) /*Initialize distance of all the vertex to INFINITY and Dset as false*/
{
parent[0] = -1;
dist[i]=INT_MAX;
Dset[i]=false;
}
dist[src]=0; /*Initialize the distance of the source vertec to zero*/
for(int c=0;c<V;c++)
{
int u=minimumDist(dist,Dset); /*u is any vertex that is not yet included in Dset and has minimum distance*/
Dset[u]=true; /*If the vertex with minimum distance found include it to Dset*/
for(int v=0;v<V;v++)
/*Update dist[v] if not in Dset and their is a path from src to v through u that has distance minimum than current value of dist[v]*/
{
if(!Dset[v] && graph[u][v] && dist[u]!=INT_MAX && dist[u]+graph[u][v]<dist[v])
{parent[v] = u;
dist[v]=dist[u]+graph[u][v];}
}
}
/*will print the vertex with their distance from the source to the console */
if(dist[n-1]<999)
{cout<<"atstumas nuo "<<src+1<<" iki "<<n<<" yra = "<<dist[n-1]<<endl;
printPath(parent, n-1);}
else
cout<<"kelio i pabaigos taska nera"<<endl;
}
int main()
{
int start,ending;
cout<<"iveskite pradzia"<<endl;
cin>>start;
cout<<"iveskite pabaiga"<<endl;
cin>>ending;
int graph[V][V]={
{ 0,70,50,0,100,0 },
{ 0,0,0,35,0,20 },
{ 0,60,0,15,0,0 },
{ 0,0,0,0,30,45 },
{ 0,0,20,0,0,0 },
{ 0,0,0,0,4,0}};
dijkstra(graph,start-1,ending);
return 0;
}

My c++ Code is not working for a Graph

I am writing a code for a graph in c++ but there is some problem. It is not working properly. Please help me what is the problem with it? Its code for a graph which can take inputs for graph from user and each edge in graph has specific weight.
Here is the code:
#include <iostream>
#include <vector>
using namespace std;
struct edge {
char src;
char dest;
int weight;
};
class Graph {
public:
vector<edge> edges;
int size,j=0;
//Constructor
Graph(int c) {
size=c;
}
void graphDesign(char s,char d,int w) {
edges[j].src=s;
edges[j].dest=d;
edges[j].weight=w;
j++;
}
void printGraph() {
for(int i=0; i<size; i++) {
cout<<edges[i].src<<"->"<<edges[i].dest<<" :
<<edges[i].weight<<endl;
}
}
};
int main() {
int e,i,w;
char s,d;
cout<<"Enter number of edges of graphs: ";
cin>>e;
Graph graph(e);
for(i=0; i<e; i++) {
cout<<"Enter source: ";
cin>>s;
cout<<"Enter destination: ";
cin>>d;
cout<<"Enter weight of the edge: ";
cin>>w;
graph.graphDesign(s,d,w);
}
graph.printGraph();
return 0;
}
One issue is here:
void graphDesign(char s,char d,int w) {
edges[j].src=s;
edges[j].dest=d;
edges[j].weight=w;
j++;
}
Since edges is an empty vector, accessing edges[j] is an illegal access.
You need to size the edges vector appropriately before you use it.
class Graph {
public:
vector<edge> edges;
//Constructor
Graph(int c) : edges(c) {}
This creates a vector with c entries.
Also, do not use extraneous, unnecessary member variables such as size here. The vector class has a size() member function to tell you how many items are in the container.
Using extraneous variables like size runs the risk of bugs occurring due to having to update this variable anytime the vector changes size. Instead of trying to do this housekeeping yourself, use the size() function provided to you by std::vector.

I'am trying to implement BFS and count all the visited node through the edges. But my code giving me 0 count except the 1st one

In this code I just want to visit the node and count the edges. For the 1st time it seems good but when I pass new nodes and edges it is giving 0 count. I find out that it's condition is not true for the next nodes and edges. It's my first implementation of BFS.
#include<bits/stdc++.h>
using namespace std;
vector<int>v[1000];
int level[1000];
bool vis[1000];
void bfs(int s,int E)
{
int count=0;
queue<int>q;
q.push(s);
level[s]=0;
vis[s]=true;
while(!q.empty())
{
int p=q.front();
q.pop();
for(int i=0;i<v[p].size();i++)
{
if(vis[v[p][i]] == false)
{
level[v[p][i]] = level[p]+1;
q.push(v[p][i]);
vis[v[p][i]] = true;
count++;
}
}
}
cout<<count<<endl;
}
int main()
{
int N,E,x,y,size;
while(scanf("%d %d",&N,&E)==2)
{
for(int i=1;i<=E;i++)
{
scanf("%d %d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
int s=0;
bfs(s);
}
return 0;
}
You are not resetting whatever variables you have used like your adjacency list v,level and vis.
You have to reset them to some default value before working on a different graph, as values of previous graphs are unwanted.
You can simply run a loop, before each input:
for(int i=0;i<N;i++)
{
v[i].clear();
vis[i]=0;
level[i]=-1;
}

A C++ implementation of topological ordering

This morning I was doing my C++ class assignment, an implementation of topological ordering. There's no error while compiling, but simply can't run. Since I'm not quite familiar with pointers or STL, nor the VS debugger...I just can't figure out where went wrong. It would help me a lot if someone can point out my errors. Tons of thanks!
Here's my code:
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
typedef struct Vertex{
int index;
int indegree; // indegree of vertex v is the total num of edges like(u,v)
vector<Vertex>adjacent;
int topoNum; // topological order of this vertex.
}Vertex;
typedef struct Edge{
Vertex start;
Vertex in;
}Edge;
Vertex*InDegrees(int numVertex,int numEdge,Edge*edges) // calculate indegrees of all vertices.
{
Vertex*vertices=new Vertex[numVertex];
for(int i=0;i<numVertex;i++){ vertices[i].index=i; vertices[i].indegree=0;}
for(int i=0;i<numEdge;i++)
{
int j=edges[i].in.index;
vertices[j].indegree++;
vertices[j].adjacent.push_back(edges[i].start);
}
return vertices;
}
int*topoSort(int numVertex,int numEdge,Edge*edges)
{
edges=new Edge[numEdge];
Vertex*Vertices=new Vertex[numVertex];
Vertices=InDegrees(numVertex,numEdge,edges);
queue<Vertex>q;
for(int i=0;i<numVertex;i++)
{
if(Vertices[i].indegree==0)
q.push(Vertices[i]);
}
int count=0;
while(!q.empty()) // Ordering completed when queue is empty.
{
Vertex v=q.front(); // get the vertex whose indegree==0
q.pop();
v.topoNum=++count;
vector<Vertex>::iterator iter;
for(iter=v.adjacent.begin();iter!=v.adjacent.end();iter++)
{
Vertex w=*iter;
if(--w.indegree==0)
q.push(w);
}
}
int*topoOrder=new int[numVertex];
for(int i=0;i<numVertex;i++)
{
int j=Vertices[i].topoNum;
topoOrder[j]=-1; // initial value, in case cycle existed.
topoOrder[j]=Vertices[i].index;
}
delete[]Vertices;
delete[]edges;
return topoOrder;
}
int main()
{
int numVertex,numEdge;
cin>>numVertex>>numEdge;
Edge*Edges=new Edge[numEdge];
int indexStart,indexIn;
for(int i=0;i<numEdge;i++)
{
cin>>indexStart>>indexIn;
Edges[i].in.index=--indexIn;
Edges[i].start.index=--indexStart;
}
int*topoOrder=new int[numVertex];
topoOrder=topoSort(numVertex,numEdge,Edges);
for(int i=0;i<numVertex-1;i++)
{
if(topoOrder[i]==-1)
{
cout<<"Cycle exists, not a DAG!";
return 0;
}
cout<<topoOrder[i]<<",";
}
cout<<topoOrder[numVertex-1]<<endl;
delete[]Edges;
return 0;
}
An obvious starting point for your problems is the allocation for Edges: the allocation uses the uninitialized value numEdge which is likely to be zero. That is, you'll get a pointer to no elements. You probably want to allocate Edges only after having read numEdge. I didn't really had a look at what happens in the actual algorithm.
I also strongly recommend that you verify that the input operations were successful:
if (std::cin >> numVertex >> numEdge) {
use_successfully_read(numVertex, numEdge);
}
If inputs fail the variable remain unchanged and the values will also lead to interesting behavior.

Digraph arc list implementation

I'm trying to implement graph as the Arc List, and while this implementation works efficiency is horrible, anything i missed that's making it so slow? Time was measured as the average of looking for arcs from/to each node.
struct Arc
{
int start;
int end;
Arc(int start,int end)
: start(start),
end(end)
{ }
};
typedef vector<Arc> ArcList;
class AListGraph
{
public:
AListGraph(IMatrix* in); //Fills the data from Incidence Matrix
bool IsE(int va,int vb); //checks if arc exists a->b
int CountEdges(); //counts all the arcs
int CountNext(int v); //counts all outgoing arcs from v
int CountPrev(int v); //counts all arcs incoming to v
private:
ArcList L;
int VCount;
};
//Cut out constructor for clarity
int AListGraph::CountEdges()
{
return L.size();
}
int AListGraph::CountNext(int v)
{
int result=0;
for(ArcList::iterator it =L.begin();it!=L.end();it++)
{
if(it->end==v)result++;
}
return result;
}
int AListGraph::CountPrev(int v)
{
int result=0;
for(ArcList::iterator it =L.begin();it!=L.end();it++)
{
if(it->start==v)result++;
}
return result;
}
Well, your implemention is worst possible : in order to find the in/out edges you have go across the whole graph.
Do you really need an arc list? Usually an adjacency list is much more efficient.
A naïve implementation of an adjacency list would be to keep an vector > arcs where the size of the arc is the number of nodes.
Given an node u, arcs[u] gives you all the out edges. You can figure out how to optimize it for in edges also.