I use C language, and apply Dynamic Programming to solve the Travelling salesman problem. There is such a problem on ZeroJudge, An Online Judge System For Beginners, but I get Segmentation fault (core dumped) on the 13th, 14th, and 15th test cases. I have checked my code, but I can’t find the problem.
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
#define min(a, b)(a > b ? b : a)
void travel();
int **map,**dp,n;
main()
{
scanf("%d", &n);
map = (int **)calloc(n, sizeof(int *));
dp = (int **)calloc(n, sizeof(int *));
for(int i = 0 ; i < n ; i++)
{
map[i] = (int *)calloc(n, sizeof(int));
dp[i] = (int *)calloc((1 << (n - 1)), sizeof(int));
}
int distance;
for(int i = 0 ; i < n ; i++)
{
for(int j = 0 ; j < n ; j++)
{
scanf("%d", &distance);
map[i][j] = distance;
}
dp[i][0] = map[i][0];
}
travel();
printf("%d\n", dp[0][(1 << (n - 1)) - 1]);
free(map);
free(dp);
}
void travel()
{
for(int j = 1 ; j < 1 << (n - 1) ; j++)
{
for(int i = 0 ; i < n ; i++)
{
dp[i][j] = INT_MAX;
if(j >> (i - 1) & 1)
{
continue;
}
for(int k = 1 ; k < n ; k++)
{
if(!(j >> (k - 1) & 1))
{
continue;
}
dp[i][j] = min(dp[i][j], map[i][k] + dp[k][j ^ (1 << (k - 1))]);
}
}
}
}
Content
Given a set of cities and the distances between each pair of cities, find the shortest distance sum of a tour that starts from a city, visits all the cities without repetition, and returns to the starting city.
For example, the visiting order is 1-2-3-4-1. The distance sum is 10 + 25 + 30 + 15 = 80.
Input Description
There is only one set of test data. The first line of each set has an integer N, indicating that there are N cities. Then there will be N lines, each line has N non-negative integers Di,j indicating the distance from node i to node j. If Di,j = 0, it is considered that there is no edge.
You can assume that each edge may be unidirectional, and guarantee that there is at least one TSP path.
* 3 < N ≤ 35
* 0 distance between any pair of cities ≤ 10000
Output Description
Output a line of minimum distance sum.
Example input #1
4
0 10 15 20
10 0 35 25
15 35 0 30
20 25 30 0
Example Output #1
80
The problem statement says “3 < N ≤ 35”. The program uses 1 << (n - 1)
in several places, where n
contains the value of N. This shifts the int
value 1 by as much as 34 bits. However, int
is commonly 32 bits in current C implementations, so shifting by more than 30 bits overflows, and the behavior is not defined by the C standard.
Further, the program attempts to allocate space for an array of 1 << (n - 1)
int
elements, in calloc((1 << (n - 1)), sizeof(int))
. This may fail due to being too large a request, especially since it is repeated N times. Or the overflow in 1 << (n - 1)
may result in insufficient memory being requested.
You need a new algorithm that does not attempt to use so much memory.