wrong output for inf=INT_MAX - c++

Below code is for Bellman Ford algorithm and it gives wrong output when I use const int INF=INT_MAX but correct output when I use const int INF=1e9 in line number 3.
Any idea why?
Code:
#include"bits/stdc++.h"
using namespace std;
const int INF=1e9;
int main()
{
int n,m;
cin>>n>>m;
vector<vector<int>> edges;
for(int i=0;i<m;i++)
{
int u,v,w;
cin>>u>>v>>w;
edges.push_back({u,v,w});
}
int src;
cin>>src;
vector<int> dist(n,INF);
dist[src]=0;
for(int iter=0;iter<n-1;iter++)
{
for(auto e:edges)
{
int u=e[0];
int v=e[1];
int w=e[2];
dist[v]=min(dist[v],w+dist[u]);
}
}
for(auto i:dist)
{
cout<<i<<" ";
}
}
Sample Input:
5 8
1 2 3
3 2 5
1 3 2
3 1 1
1 4 2
0 2 4
4 3 -3
0 1 -1
0
Expected Output:
0 -1 2 -2 1

Signed integer overflow here w+dist[u]. The simple fix:
dist[v] = static_cast<int>(min(static_cast<long long>(dist[v]), static_cast<long long>(w) + dist[u]));

Related

Print common elements in an array intersection

Given two arrays - array arr and array art of size n and m respectively. We have to find intersection of arrays
My solution -
#include<iostream>
#include<climits>
using namespace std;
void inputarray(int arr[],int size){
for(int i=0;i<size;i++){
cin>>arr[i];
}
}
void logic(int arr1[],int size1,int arr2[],int size2){
for(int i=0;i<size1;i++){
int element = arr1[i];
for(int j=0;j<size2;j++){
if(element==arr2[j]){
cout<<element;
arr2[j]=INT_MIN;
break;
}
}
}
}
int main(){
int arr1[100];
int arr2[100];
int size1;
cin>>size1;
int size2;
cin>>size2;
inputarray(arr,size1);
inputarray(arr,size2);
logic(arr1,size1,arr2,size2);
}
But for this abovw solution answer is coming wrong.
Answer Coming is -
6
4
1 2 2 2 3 4
2 2 3 3
2233
Expected Answer is -
6
4
1 2 2 2 3 4
2 2 3 3
223
So please tell where is the problem and how can i solve ?
Errors like this one show how important variable naming is...
In the line:
if(ele==arr[j]){
you are mistaking arr with art...

Generate the lexicographically first permutation(recursive backtracking)

The input is a number n, a number m, and an array of size 3*n, whose elements are either 0s or numbers from 1 to n, where 1<=n,m<=30. I need to make an algorithm to generate the lexicographically first permutation of the set{1,...,n}, where every element appears exactly 3 times, where two equal numbers have a minimum ofm different numbers between them. Only the 0s are to be replaced, while any number that isn't 0 has to stay the same.
For example, for n=5, m=1 and the array 1 0 0 0 0 0 3 0 0 0 0 0 0 4 5 the output should be 1 2 1 2 1 2 3 4 3 5 3 4 5 4 5.
I came up with this code. It doesn't output the lexicographically first permutation. It outputs
1 2 3 4 5 1 3 2 3 4 5 1 2 4 5
#include <array>
#include <iostream>
using namespace std;
int counters[100]={3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3};
bool verify_permutation(int V[], int n, int m){
array<int,100> POZ;
POZ.fill(m);;
for(int i = 1;i<=3*n;i++){
if(V[i]==0)
return false;
for(int j = 1;j<=3*n;j++){
if(POZ[V[j]]<m)
return false;
POZ[V[j]]=0;
for(int k = 1;k<=n;k++){
POZ[k]++;
}
}
}
return true;
}
int j = 1;
void backtracking(int V[], int x, int m, int n){
if(verify_permutation(V,n,m)){
for(int i = 1;i<=3*n;i++)
cout<<V[i]<<' ';
return;
}
for(int i=1;i<=3*n;i++){
if(counters[j]==0)
continue;
if(V[i]!=0){
counters[V[i]]--;
continue;
}
j++;
if(j>n)
j=1;
if(V[i]==0){
counters[j]--;
V[i]=j;
backtracking(V,j,m,n);
counters[j]++;
}
}
return;
}
int main(){
int V[31];
int n,m;
cin>>n>>m;
if(m>=n){
cout<<-1;
return 0;
}
for(int i = 1; i <= 3*n; i++){
cin >> V[i];
}
backtracking(V, 1, m, n);
}
What is wrong with the code?

Code produce two different upon removing if statement

While I was solving a question from codeforces(link to the question: https://codeforces.com/contest/1466/problem/A) I encountered weird output from the below code
#include<iostream>
#include<vector>
#include<set>
using namespace std;
void solve(){
int64_t n;
cin>>n;
if (n<2){
cout<<0<<endl;
return;
}
vector<int64_t> vec(n, 0);
for(auto &i: vec){
cin>>i;
}
set<int64_t> s;
for(int64_t i=0; i<n-1; ++i){
for(int64_t j=i+1; j<n; ++j){
s.insert(vec[j]-vec[i]);
}
}
cout<<s.size()<<endl;
}
int main(){
int64_t t;
cin>>t;
while(t--){
solve();
}
return 0;
}
Input:
8
4
1 2 4 5
3
1 3 5
3
2 6 8
2
1 2
1
50
5
3 4 5 6 8
3
1 25 26
6
1 2 4 8 16 32
Ouptut given by my code:
4
2
3
1
0
53
1
1
When I removed if block it passed all the pretests/testcases.
if (n<2){
cout<<0<<endl;
return;
}
Expected output:
4
2
3
1
0
5
3
15
After removing the if block I get the same output as above. I'm not able to understand how if block is affecting the size of set in the next iteration.
Compiled with g++ same output with -std=c++11 -std=c++14 and -std=c++17
if (n<2){
cout<<0<<endl;
return;
}
Since you're returning here, it means that if n is 1, you never read that one value out of std::cin.
If you remove that if, then that one value will get read in here:
vector<int64_t> vec(n, 0);
for(auto &i: vec){
cin>>i;
}
So if you want the if to work as expected, it should be:
if (n<2){
cout<<0<<endl;
if(n == 1) { std::cin >> n; } // remove 1 item from stream
return;
}

What is resetting the value of the iterator in this for-loop?

#include <iostream>
using namespace std;
int main() {
const int SIZE = 5;
double x[SIZE];
for(int i = 2; i <= SIZE; i++) {
x[i] = 0.0;
cout << i << endl;
}
}
Output:
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
...
If SIZE is initialized to a different value, the iterator will iterate until it is one short of that value and then reset back to zero. If the array of x is changed to data type int, the loop does not get stuck on itself. If the assignment value to x[i] is changed to any non-zero number, the value of is changed to garbage during the last run of the loop.
#include <iostream>
using namespace std;
int main() {
const int SIZE = 5;
double x[SIZE];
for(int i = 2; i <= SIZE; i++) {
x[i] = 1;
cout << i << endl;
}
}
Output:
2
3
4
1072693248
#include <iostream>
using namespace std;
int main() {
const int SIZE = 5;
int x[SIZE];
for(int i = 2; i <= SIZE; i++) {
x[i] = 1;
cout << i << endl;
}
}
Output:
2
3
4
5
You are writing past the end of the x array. x[] ranges from 0 to SIZE - 1 (or 4), and you let your index i == SIZE.
So, the behavior is undefined and coincidentally, you are overwriting i when you write x[5].
Use a debugger. It's your friend.
for(int i = 2; i < SIZE; i++) // i <= SIZE will write beyond the array
Your current array is of size 5. Arrays are 0 indexed:
1st element last element
0 1 2 3 4
You're iterating past the end of your array (i <= 5), which is undefined behavior.
Your end condition is wrong. Use i < SIZE
#include <iostream>
using namespace std;
int main() {
const int SIZE = 5;
double x[SIZE];
for(int i = 2; i < SIZE; i++) {
x[i] = 0.0;
cout << i << endl;
}
}

Nested for loops recursion

I looked up in many places and tried to understand how to get arbitrary number of nested for loops via recursion. But what I have understood is clearly wrong.
I need to generate coordinates in an n-dimensional space, in a grid-pattern. The actual problem has different coordinates with different ranges, but to get simpler things right first, I have used the same, integer-stepped coordinate ranges in the code below.
#include <iostream>
using namespace std;
void recursion(int n);
int main(){
recursion(3);
return 0;
}
void recursion(int n)
{
if(n!=0){
for(int x=1; x<4; x++){
cout<<x<<" ";
recursion(n-1);
}
}
else cout<<endl;
}
I want, and was expecting the output to be:
1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
1 3 1
1 3 2
1 3 3
2 1 1
2 1 2
2 1 3
2 2 1
2 2 2
2 2 3
2 3 1
2 3 2
2 3 3
3 1 1
3 1 2
3 1 3
3 2 1
3 2 2
3 2 3
3 3 1
3 3 2
3 3 3
Instead, the output I'm getting is
1 1 1
2
3
2 1
2
3
3 1
2
3
2 1 1
2
3
2 1
2
3
3 1
2
3
3 1 1
2
3
2 1
2
3
3 1
2
3
I just can't figure out whats wrong. Any help to figure out the mistake or even another way to generate coordinates will be greatly appreciated. Thanks!
Non-recursive solution based on add-with-carry:
#include <iostream>
using namespace std;
bool addOne(int* indices, int n, int ceiling) {
for (int i = 0; i < n; ++i) {
if (++indices[i] <= ceiling) {
return true;
}
indices[i] = 1;
}
return false;
}
void printIndices(int* indices, int n) {
for (int i = n-1; i >= 0; --i) {
cout << indices[i] << ' ';
}
cout << '\n';
}
int main() {
int indices[3];
for (int i=0; i < 3; ++i) {
indices[i] = 1;
}
do {
printIndices(indices, 3);
} while (addOne(indices, 3, 3));
return 0;
}
Recursive solution, salvaged from your original code:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
void recursion(int n, const string& prefix);
int main(){
recursion(3, "");
return 0;
}
void recursion(int n, const string& prefix)
{
if (n!=0) {
for(int x=1; x<4; x++){
ostringstream os;
os << prefix << x << ' ';
recursion(n-1, os.str());
}
}
else cout << prefix << endl;
}
Per Igor's comment, you need an increment function.
Let's use an std::vector to represent each dimension. That is vector[0] is the first dimension, vector[1] is the second dimension and so on.
Using a vector allows us to determine the number of dimensions without any hard coded numbers. The vector.size() will be the number of dimensions.
Here is a function to get you started:
void Increment_Coordinate(std::vector<int>& coordinates,
int max_digit_value,
int min_digit_value)
{
unsigned int digit_index = 0;
bool apply_carry = false;
do
{
apply_carry = false;
coordinates[digit_index]++; // Increment the value in a dimension.
if (coordinates[digit_index] > max_digit_value)
{
// Reset the present dimension value
coordinates[digit_index] = min_digit_value;
// Apply carry to next column by moving to the next dimension.
++digit_index;
apply_carry = true;
}
} while (apply_carry);
return;
}
Edit 1
This is only a foundation. The function needs to be boundary checked.
This function does not support dimensions of varying sizes. That is left as an exercise for reader or OP.