UVA(769) :critical links getting wrong answer - c++

I am solving Critical links problem on UVA.The problem is about finding the bridges in the Graph.I used the same algorithm here.But I am continuously getting wrong answer.
Please suggest what's wrong with my code.
//Bridges in a Graphs
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<stack>
#include<utility>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define MAX 205
int parent[MAX],timer=0,low[MAX],disc[MAX];
bool vis[MAX];
vector<pair<int,int> >st;
vector<vector<int> >G(MAX);
bool cmp(const pair<int,int> a,pair<int,int> b)
{
if(a.first==a.second)
return a.second<b.second;
else
return a.first<b.first;
}
void reset()
{
st.clear();
memset(parent,-1,sizeof parent);
memset(vis,false,sizeof vis);
for(int i=0;i<=MAX;i++)
G[i].clear();
}
void dfs(int u)
{
vis[u]=true;
disc[u]=low[u]=timer++;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(!vis[v])
{
parent[v]=u;
dfs(v);
low[u]=min(low[u],low[v]);
if(low[v]>low[u])
st.push_back(make_pair(min(u,v),max(u,v)));
}
else if(v!=parent[u])
low[u]=min(low[u],disc[v]);
}
}
int main()
{
int n,t=0;
while(cin>>n)
{
reset();
if(t>0)
cout<<endl;
if(n==0)
{
cout<<"0"<<" critical links\n";break;
}
int node,count;
for(int j=0;j<n;j++)
{
scanf("%d (%d)",&node,&count);
for(int i=0;i<count;i++)
{
int x;
scanf("%d",&x);
G[node].push_back(x);
G[x].push_back(node);
}
}
for(int i=0;i<n;i++)
{
if(!vis[i])
dfs(i);
}
sort(st.begin(),st.end(),cmp);
cout<<st.size()<<" critical links\n";
for(int i=0;i<st.size();i++)
cout<<st[i].first<<" - "<<st[i].second<<endl;
t++;
}
}

Finally I got it,little bit flaw in std::sort cmp function and it is
bool cmp(const pair<int,int> a,pair<int,int> b)
{
if(a.first==b.first)
return a.second<b.second;
else
return a.first<b.first;
}
also in dfs function low[v]>disc[u] instead of low[v]>low[u].

Related

Binary search optimisation

I implemented binary search in two ways and wondering which is more efficient? please help me know which is more efficient and how can it further be optimized? is time complexity remains same in both approach? I am a beginner in programming.
approach 1;
#include<iostream>
using namespace std;
bool BinarySearch(int*a,int n,int s ){
if(n==1){
if(a[0]==s)
return true;
else
return false;
}
else{
if(s<a[n/2]){
int U[n/2];
for(int i=0;i<n/2;i++){
U[i]=a[i];
}
return BinarySearch(U,n/2,s);
}
else{
int V[n-n/2];
for(int i=0;i<n-n/2;i++){
V[i]=a[i+n/2];
}
return BinarySearch(V,n-n/2,s);
}
}
}
int main(){
int array[10]={2,4,6,8,10,12,14,16,18,22};
cout<<BinarySearch(array,10,9);
}
approach 2:
#include<iostream>
using namespace std;
bool Bsearch(int arr[],int s,int l,int x){
cout<<"calling bsearch with arguments "<<s<<' '<<l<<' '<<x<<endl;
if(l==1)
return arr[s]==x;
int h=l/2;
if(x<arr[s+h])
return Bsearch(arr,s,h,x);
else
return Bsearch(arr,s+h,l-h,x);
}
int main(){
int marks[11]={17,18,20,22,24,26,28,30,32,34,36};
cout<<Bsearch(marks,0,11,32);
}
Thanks in advance for the kind help.
Other posters are correct that variable-length arrays are not good C++. If you define your main() as:
int main() {
std::array<int> marks{17,18,20,22,24,26,28,30,32,34,36};
cout<<Bsearch(marks,0,32);
}
or:
int main() {
std::vector<int> marks{17,18,20,22,24,26,28,30,32,34,36};
cout<<Bsearch(marks,0,32);
}
then you can drop the pointer/length pair in the parameter list to your binary-search function. The function prototype becomes something like:
bool Bsearch(const std::array<int>& arr, int s, int x);

in c++ expected primary expression before ']'

Here is my code for quick sort. I am a beginner kindly please help.
#include<iostream>
using namespace std;
class quick
{
private:
int n,left,right,i,j;
float a[55];
public:
void getdata();
void sort(float[],int,int);
void putdata();
};
void quick::getdata()
{
cout<<"Enter how many elements you want to enter:";
cin>>n;
for(int k=0;k<n;k++)
{
cout<<"Enter percentage of students:"<<k+1<<":";
cin>>a[k];
}
left=0;
right=n-1;
}
void quick::putdata()
{
for(int k=0;k<5;k++)
{
cout<<"\nSorted marks are:"<<a[k]<<endl;
}
}
void quick::sort(float a[],int left,int right)
{
if(left<right)
{
int i=left;
int j=right+1;
float pivot=a[left];
do{
do{
i++;
}while((a[i]<pivot)&& left<right);
do{
j--;
}while(a[j]>pivot);
if(i<j)
swap(a[i],a[j]);
}while(i<j);
a[left]=a[j];
a[j]=pivot;
sort(a,left,j-1);
sort(a,j+1,right);
}
}
int main()
{
quick obj;
obj.getdata();
obj.sort(a[],left,right);
obj.putdata();
return (0);
}
It is giving me error in int main() function:
a is not declared in this scope.
expected primary expression before ']'.
As the answer is given by #Shubham Khatri. Here is the corrected code.
#include<iostream>
using namespace std;
class quick
{
public: int n,left,right,i,j;
float a[55];
public:
void getdata();
void sort(float[],int,int);
void putdata();
};
void quick::getdata()
{
cout<<"Enter how many elements you want to enter:";
cin>>n;
for(int k=0;k<n;k++)
{
cout<<"Enter percentage of students:"<<k+1<<":";
cin>>a[k];
}
left=0;
right=n-1;
}
void quick::putdata()
{
for(int k=0;k<n;k++)
{
cout<<"\nSorted marks are:"<<a[k]<<endl;
}
}
void quick::sort(float a[],int left,int right)
{
if(left<right)
{
int i=left;
int j=right+1;
float pivot=a[left];
do{
do{
i++;
}while((a[i]<pivot)&& left<right);
do{
j--;
}while(a[j]>pivot);
if(i<j)
swap(a[i],a[j]);
}
while(i<j);
a[left]=a[j];
a[j]=pivot;
sort(a,left,j-1);
sort(a,j+1,right);
}
}
int main()
{
quick obj;
obj.getdata();
obj.sort(obj.a,obj.left,obj.right);
obj.putdata();
return (0);
}
As it mentions you have not declared a as a variable inside the int main(). Rather it is an object of quick. In a function you don't pass array like a[] rather as a only .since a, left, right are a private variable of a class you can't access it from the object directly. Declare it as public and use it as obj.a, obj.left, obj.right inside sort function.
Complete code:
#include<iostream>
using namespace std;
class quick
{
public:
int n,left,right,i,j;
float a[55];
void getdata();
void sort(float[],int,int);
void putdata();
};
void quick::getdata()
{
cout<<"Enter how many elements you want to enter:";
cin>>n;
for(int k=0;k<n;k++)
{
cout<<"Enter percentage of students:"<<k+1<<":";
cin>>a[k];
}
left=0;
right=n-1;
}
void quick::putdata()
{
for(int k=0;k<5;k++)
{
cout<<"\nSorted marks are:"<<a[k]<<endl;
}
}
void quick::sort(float a[],int left,int right)
{
if(left<right)
{
int i=left;
int j=right+1;
float pivot=a[left];
do{
do{
i++;
}while((a[i]<pivot)&& left<right);
do{
j--;
}while(a[j]>pivot);
if(i<j)
swap(a[i],a[j]);
}while(i<j);
a[left]=a[j];
a[j]=pivot;
sort(a,left,j-1);
sort(a,j+1,right);
}
}
int main()
{
quick obj;
obj.getdata();
obj.sort(obj.a,obj.left,obj.right);
obj.putdata();
return (0);
}

how to efficiently appraoch for SPOJ Square free numbers?

I tried my best to solve Spoj problem No Squares numbers but I'm getting (TLE). Please tell how to approach. I'm unable to find any proper approach. Here is my code:
#include <bits/stdc++.h>
using namespace std;
#define size 10000004
int mark[size+1];
void sieve()
{
for(int i=2,k;(k=i*i)<=size;++i)
{
for(int j=k;j<=size;j=j+k)
mark[j]=-1;
}
}
int fn(int a,int b,int c)
{
int i,j,k,cnt=0;
for(i=a;i<=b;++i)
{
j=i;
if(mark[j]!=-1)
{
while(j>0)
{
if(j%10==c)
{
cnt+=1;
break;
}
else
j=j/10;
}
}
}
return cnt;
}
int main()
{
sieve();
int t,a,b,c;
cin>>t;
for(int i=0;i<t;t++)
{
cin>>a>>b>>c;
cout<<fn(a,b,c)<<endl;
}
}

segmentation fault because of comparison function

I tried solving this probblem on spoj. http://www.spoj.com/problems/BUSYMAN/
Although I was able to solve it but I got a very strange error. I tried understanding the cause of it but failed. I have two codes.
///////////////////////////////////////////////////
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class activity
{
public:
int start,end;
};
bool comp(activity p, activity q)
{
if(p.end<q.end)return true;
if(p.end==q.end&&p.start<=q.start)return true;
return false;
}
int main()
{
int t;
cin>>t;
vector<activity> v;
for(int i=0;i<t;i++)
{
int n;
cin>>n;
v.resize(n);
for(int j=0;j<n;j++)cin>>v[j].start>>v[j].end;
sort(v.begin(),v.end(),comp);
int ans=0,currend=0;
for(int j=0;j<n;j++)
{
if(v[j].start>=currend){ans++;currend=v[j].end;
}
}
cout<<ans<<endl;
}
}
/////////////////////////////////////////////
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class activity
{
public:
int start,end;
};
bool comp(activity p, activity q)
{
if(p.end<q.end)return true;
if(p.end==q.end&&p.start>=q.start)return true;
return false;
}
int main()
{
int t;
cin>>t;
int n;
vector<activity> v;
for(int i=0;i<t;i++)
{
cin>>n;
v.resize(n);
for(int j=0;j<n;j++)
cin>>v[j].start>>v[j].end;
sort(v.begin(),v.end(),comp);
int ans=0,currend=0;
for(int j=0;j<n;j++)
{
if(v[j].start>=currend)
{
ans++;currend=v[j].end;
}
}
cout<<ans<<endl;
}
}
//////////////////////////////
My problem is that the first one gives segmentation fault on spoj while second one does not. The only difference between the two is the comparison function. I just happen to define the second statement of the comparison function in two different ways which are similar. But it gives me segmentation fault in the first case but not in second case.
enter image description here
In the two images above there are two codes with respective submission ids and in the third it shows seg fault for one while not for other. You can verify with the submission ids on my spoj profile as well.
Because bool comp(activity p, activity q) doesn't meet requirements of Compare see std::sort
It should be this:
bool comp(const activity& p, const activity& q)
{
return p.end < q.end || (p.end ==q.end && p.start < q.start);
}
or
struct comp {
bool operator()(const activity& p, const activity& q) const
{
return p.end < q.end || (p.end ==q.end && p.start < q.start);
}
};
or
struct comp {
bool operator()(const activity& p, const activity& q) const
{
return std::tie(p.end, p.start) < std::tie(q.end, q.start);
}
};
The rules of C++ are that the comparator for std::sort must give a strict weak ordering.
So, the comparator must return false for equal elements. However this test:
if(p.end<q.end)return true;
if(p.end==q.end&&p.start<=q.start)return true;
return false;
returns true if the elements are equal, so this is an invalid comparator.
In your second attempt:
if(p.end<q.end)return true;
if(p.end==q.end&&p.start>=q.start)return true;
return false;
This has the same problem, also causing undefined behaviour.
You can't infer anything from the observed behaviour when the code had undefined behaviour, it is just chance (perhaps depending on some detail about your compiler's particular choice of sort algorithm) as to what behaviour you get.
Changing <= to < in the first comparator would yield a valid comparator with sort order of both end and start ascending.

C++ What's wrong with my DFS code?

I have tried to code the DFS algorithm as given in CLRS. Here's the code below. When I run it I got an error as "Your program stopped unexpectedly." When I debugged the code I got this line in the call stack "msvcrt!malloc()" and "operator new(unsigned int)". I'm using CodeBlocks. Where am I wrong?
#include<iostream>
#include<cstdlib>
#include<vector>
#include<list>
#include<utility>
#include<algorithm>
#include<string>
using namespace std;
struct prop
{
int p;
int value;
int d;
int f;
string color;
};
vector<prop>v;
prop make_prop(int a,int b,int c,int d,string e)
{
prop p = {a,b,c,d,e};
return p;
}
class Dfs
{
public:
int time;
vector<list<int> >adj;
Dfs(int nv)
{
v.resize(nv);
adj.resize(nv);
for(int i=0;i<nv;i++)
{
v[i].value = i;
v[i].p = -1;
v[i].color = "WHITE";
}
}
void addinput()
{
adj[0].push_back(1);
adj[0].push_back(2);
adj[0].push_back(3);
adj[1].push_back(0);
adj[1].push_back(3);
adj[2].push_back(0);
adj[2].push_back(3);
adj[3].push_back(0);
adj[3].push_back(1);
adj[3].push_back(2);
}
void dfs();
void dfsvisit(prop);
};
void Dfs::dfs()
{
time = 0;
for(int i=0;i<v.size();i++)
{
if(v[i].color == "WHITE")
{
dfsvisit(v[i]);
}
}
}
void Dfs::dfsvisit(prop m)
{
time++;
m.d = time;
m.color = "GRAY";
int val = m.value;
for(auto it = adj[val].begin();it != adj[val].end();it++)
{
if(v[*it].color == "WHITE")
{
v[*it].p = val;
dfsvisit(v[*it]);
}
}
m.color = "BLACK";
cout<<m.value;
time++;
m.f = time;
}
int main()
{
Dfs d(4);
d.addinput();
d.dfs();
return 0;
}
void Dfs::dfsvisit(prop m) // should be prop&
dfsvisit(prop m) will make a copy of the property while dfsvisit(prop& m) receives a reference, working directly on the property you passed to the function
the stack will overflow!
In function dfsvisit,you pass parameter by value,which will never change the actual parameter.You should pass parameter by reference.
void dfsvisit(prop& m);