I am taking input from a file in following form :
3
0 1
0 2
1 0
1 2
2 0
2 1
Here 3 is unique number of numbers in the list i.e., 0,1,2.
I have successfully made a adjacency list of the list.
O/P :
0 -> 1 2
1 -> 0 2
2 -> 0 1
Using the following code
if (input.is_open())
{
cout << "File is Open. \n";
input >> totalnode;
pair<pair<int,int>, pair<int,int>> a;
vector<list<int>>adjlist(totalnode);
while (input >> node1 >> node2)
{
adjlist[node1].push_back(node2);
}
vector<list<int>>::iterator i;
int c = 0;
for ( i = adjlist.begin(); i != adjlist.end(); ++i)
{
cout << c << " -> ";
list<int> li = *i;
list<int>::iterator iter;
for ( iter = li.begin(); iter != li.end(); ++iter)
{
cout << *iter << " ";
}
cout << "\n";
c++;
}
Now I wish to make adjacency list of pairs.
Example :
0,1 -> (0,2) (1,0) (1,2) (2,0) (2,1)
0,2 -> (0,1) (1,0) (1,2) (2,0) (2,1)
1,0 -> (0,1) (0,2) (1,2) (2,0) (2,1)
I think, I should use this,
vector<pair<int, int>> asd;
or
vector<list<pair<int,int>>> asd;
How do I compare pairs? Honestly I have no idea, how to achieve this.
It depends on the requirement. As rightly said by Sam, there is default comparison overload which first compares the first field. If that is same, then it compares the second field.
If that's what you want, then just use it directly.
Otherwise, Overload comparison operator. I think in your case, you don't need it.
In your case, what you should do is maintain a map.
map<pair<int, int>, vector< pair<int, int> > > asd;
and directly use pair as key for the map.
Related
I have a doubt in a line given below of this code:
cout<<"("<<c<<","<<(*i).get_vertex()<<") value of this pair : "<<(*i).get_weight()<<", ";
How this get_vertex and get_weight work without the help of class edge object. The code compiled successfully and it's working too but I can't figure out how the above line is working.
Output of the code is:
Pairs for 0 are -> (0,1) value of this pair : 2, (0,2) value of this pair : 3, (0,3) value of this pair : 4,
Pairs for 1 are -> (1,2) value of this pair : 5, (1,0) value of this pair : 2,
Pairs for 2 are -> (2,3) value of this pair : 8, (2,1) value of this pair : 5,
Pairs for 3 are -> (3,0) value of this pair : 4, (3,2) value of this pair : 8,
Code is given below:
#include<bits/stdc++.h>
using namespace std;
class edge{
int weight,vertex;
public:
edge(int w , int v){
weight = w;
vertex = v;
}
int get_weight()const{
return weight;
}
int get_vertex()const{
return vertex;
}
};
int main(){
int n = 4;
int c = 0;
vector<list<edge>>adj(n) ;
adj[0].push_back(edge(2,1));
adj[0].push_back(edge(3,2));
adj[0].push_back(edge(4,3));
adj[1].push_back(edge(5,2));
adj[1].push_back(edge(2,0));
adj[2].push_back(edge(8,3));
adj[2].push_back(edge(5,1));
adj[3].push_back(edge(4,0));
adj[3].push_back(edge(8,2));
vector<list<edge>>:: iterator it ;
for(it=adj.begin();it!=adj.end();it++){
cout<<" Pairs for "<<c<<" are -> ";
list<edge>li = *it;
list<edge>::iterator i;
for(i=li.begin();i!=li.end();i++){
cout<<"("<<c<<","<<(*i).get_vertex()<<") value of this pair : "<<(*i).get_weight()<<", ";
}
cout<<endl;
c++;
}
}
Break it into chunks.
Add whitespace:
cout << "("
<< c
<< ","
<< (*i).get_vertex()
<< ") value of this pair : "
<< (*i).get_weight()
<< ", ";
Does that make more sense?
I am trying to implement the Bron-Kerbosch's algorithm, which is a recursive algorithm for clique finding. I managed to get to a point, where it returns the correct number of cliques, yet when I print them, they are not correct - additional nodes are added. Am I missing something obvious here?
I am using adjacency list structure:
vector< list<int> > adjacency_list;
where I add edges the following way:
void graph::addEdge(int i1,int i2){
//as this is an undirected graph
adjacency_list[i1].push_back(i2);
adjacency_list[i2].push_back(i1);
}
Main algorithm is the following:
void graph::BronKerbosch(vector<int> R, vector<int> P, vector<int> X){
if (P.empty() && X.empty()){
result_cliques.insert(R);
}
// vector <int> tmpVerts = P;
for(std::vector<int>::iterator it = P.begin(); it != P.end();) {
vector<int> intersection = {}, intersectionX = {};
int node = *it;
//N(P)
for (int nodeP : adjacency_list[node]){
for (int node2 : P){
if (nodeP == node2){
intersection.push_back(nodeP);
}
}
//N(X)
for (int node3 : X){
if (nodeP == node3){
intersectionX.push_back(nodeP);
}
}
}
R.push_back(node);
BronKerbosch(R,intersection,intersectionX);
//P.erase(remove(P.begin(),P.end(),node),P.end());
P.erase(it);
X.push_back(node);
}
}
And I run it within:
void graph::run_BronKerbosch(){
vector<int> R,P,X;
for (int i=1; i < adjacency_list.size(); i++) {
P.push_back(i);
}
BronKerbosch(R,P,X);
cout << "................\nClassic: " << result_cliques.size() << endl;
for (auto clique : result_cliques){
cout << "(";
for (int node : clique){
cout << node <<" ";
}
cout << ")\n";
}
}
The output problem for the following graph input:
1 2
1 3
2 3
is, that this code returns:
(1 2 3 )
(1 2 3 4 )
(1 2 3 4 5 )
whereas it should return (used python for this):
(1 2 3 )
(2 4 )
(2 5 )
Thank you very much for any help.
In the wikipedia page, the recursive call looks like this:
for each vertex v in P:
BronKerbosch1(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v))
...
In the code from the question, you do a R.push_back(node) before the recursive call, but that node will be included in R in all subsequent iterations of the loop, which is not correct.
That is, the following instructions:
R.push_back(node);
BronKerbosch(R,intersection,intersectionX);
should probably be followed by a R.pop_back(node) immediately after the recursive call.
I have a code where I am reverse iterating a map in C++. For n pairs in map, sometimes the map prints out n pairs, sometimes n-1 pairs.
for test case
4 2
2 1
3 5
2 3
1 5
it prints 4 hi's, for the next case 3 hi's
4 1
0 2
0 3
3 5
0 6
My code:
include cmath, cstdio, vector, iostream, map, algorithm, using namespace std;
int main() {
int n,f;
cin >> n >> f;
int k[n],l[n],dif[n];
map<int,int> m;
map<int,int>::reverse_iterator it;
for (int i=0;i<n;i++){
scanf("%d %d\n",&k[i],&l[i]);
dif[i] = l[i]-k[i];
m.insert(make_pair(dif[i],l[i]));
}
int a = 0;
int sum = 0;
for(it = m.rbegin(); it != m.rend(); ++it ) {
cout << "hi" << endl;
int article = it->second - it->first;
int people = it->second;
if (a < f and article!=0){
a++;
if (2*article > people){
sum = sum + people;
} else {
sum = sum + (2*article);
}
} else {
if (article > people){
sum = sum + people;
} else {
sum = sum + article;
}
}
}
cout << sum;
return 0;
}
This has nothing to do with reverse iteration, it would be the same with forward iteration. A map has a pair of a key and a value. Each key can only be included in the map once. When you insert the same key again the previous value is overwritten. In your second test case you are setting the key 0 three times:
4 1
0 2 <--
0 3 <--
3 5
0 6 <--
So your map actually only has three values, so the three "Hi" are correct. In your first example you overwrite key 2 only twice, so the four "Hi". Maybe a map is not the correct container you are looking for.
let us suppose have following pairs
0 -1
0 -2
0 -3
1- 2
2 -3
3- 4
2 -4
4- 5
5 -6
i would like to insert those pairs into vector , so that i should have each element only one times , for instance
start with empty vector :
0-1 is inserted
now we are checking 0-2 , there exist 0, but not 2, so 0-2 is inserted, we have
0-1
0-2
now 0-3 , 3 is not in the list, so we can insert
0-1
0-2
0-3
now lets us consider 1-2 , of course we have both of them , so skip, now let us consider 2-3, again we can skip, 3-4 , 3 exist but not 4, so we can insert
3-4 , after inserting of 4 , 4 also exist,so reject 2-4 then comes 4-5 and 5-6, so we have following list
0-1
0-2
0-3
3-4
4-5
5-6
i have following code
#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
struct edge
{
int a, c;
float weight;//edge a-c has weight
bool operator() (edge x, edge y)
{
x.weight < y.weight;
}
};
int noncyclical_sum(vector<edge>s)
{
int total = 0;
std::vector<std::pair<int, int>> b;
auto m = make_pair(s[0].a, s[0].c);
b.push_back(m);
total = total + s[0].weight;
vector<edge>::iterator it;
for (int i = 1; i < s.size(); i++)
{
auto m = make_pair(s[i].a, s[i].c);
//if (find(b.begin(), b.end(), s[i].a) != b.end() && find(b.begin(), b.end(), s[i].c) != b.end())
if (find(b.begin(), b.end(), m.first) != b.end() && find(b.begin(), b.end(), m.second) != b.end())
{
continue; //both element is in the vector
}
else
{
b.push_back(m);
total = total + s[i].weight;
}
std::vector<std::pair<int, int>>::iterator ii;
for (ii = b.begin(); ii != b.end(); ii++)
cout << ii->first << " " << ii->second;
}
}
int main()
{
return 0;
}
at first time , i have pushed first pair, starting from the second one, i am checking if at the same time both element is in vector, i am rejecting pairs and continue, otherwise i push new pairs and continuing , but i have following error
Severity Code Description Project File Line Suppression State
Error C2678 binary '==': no operator found which takes a left-hand operand of type 'std::pair<int,int>' (or there is no acceptable conversion) kurskal_algorithm c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.10.25017\include\xutility 3161
what is wrong ? thanks in advance
The problem is in this line:
if (find(b.begin(), b.end(), m.first) != b.end() && find(b.begin(), b.end(), m.second) != b.end())
Let's check the arguments of std::find call: b.begin() and b.end() are std::vector<std::pair<int, int>>::iterators while m.first is int.
So, you're trying to find int in the vector of pairs. You can't do that.
Also, all of your functions lack the required return statements.
I am trying to iterate through a vector of vectors neighbors and simply display its contents.
The context: Graph theory.
neighbors[i] is a vector containing all adjacent vertices to vertex i. For this example, the graph is the complete graph $K_5$ of 5 vertices all connected to each other.
Problem: I need an iterator to iterate through the sub-vectors, since I (shouldn't) know their length, but I get the wrong answer.
My attempt
for(int i = 0; i < num_vertices_h; ++i) {
for(vector<int>::iterator it = neighbors[i].begin(); it != neighbors[i].end(); ++it) {
cout << neighbors[i][*it] << " ";
}
cout << endl;
}
The (wrong) output
2 3 4 -1454373456
0 3 4 -1454373584
0 1 4 0
0 1 2 -1454373744
0 1 2 3
If I just cheat, using the fact that I know each sub-vector has 4 entries, I can avoid the iterator:
Cheat Solution
for(int i = 0; i < num_vertices_h; ++i) {
for(int j = 0; j < num_vertices_h -1; ++j) {
cout << neighbors[i][j] << " ";
}
cout << endl;
}
Correct output
1 2 3 4
0 2 3 4
0 1 3 4
0 1 2 4
0 1 2 3
If neighbors[i] is a vector itself, in your first loop attempt, *it it is actually the vector element, so you can just cout << *it and you'll have the correct result.