NPC问题,不存在多项式时间的算法,但是在算法中可以做剪枝优化:
1. 第一次写的算法,缺少剪枝: 当前路径 >= 之前算出的最短路径, 则当前路径不在继续遍历
#include <cstdio> #include <iostream> #include <cstring> using namespace std; int N; int map[12][12]; int flag[12]; int solve(int start) { int i,val, all_visited = 1, min = 999999999; for (i = 2; i <= N; i++) { if (flag[i] != 0 || map[start][i] == 0) { continue; } all_visited = 0; flag[i] = 1; //visited val = map[start][i] + solve(i); if (val < min) { min = val; } flag[i] = 0; } if (all_visited) { return map[start][1]; } else { return min; } } int main(int argc, char** argv) { int tc, T, i, j; // freopen("input.txt", "r", stdin); cin >> T; for(tc = 0; tc < T; tc++) { cin>>N; for (i = 1; i <= N; i++) { for (j = 1; j <= N; j++) { cin>>map[i][j]; } } memset(flag, 0x00, 12*sizeof(int)); printf("%d ", solve(1)); } return 0; }
2. 优化算法,路径判断剪枝
#include <cstdio> #include <iostream> #include <cstring> using namespace std; int N, cost, min_cost; int map[13][13]; int flag[13]; int sum; void solve(int start) { int i; if (sum >= N) { if (map[start][1]!=0 && cost + map[start][1] < min_cost) { min_cost = cost + map[start][1]; } return; } for (i = 2; i <= N; i++) { if (flag[i] != 0 || map[start][i] == 0 || cost + map[start][i] >= min_cost) { continue; } flag[i] = 1; //visited cost += map[start][i]; sum++; solve(i); sum--; flag[i] = 0; cost -= map[start][i]; } } int main(int argc, char** argv) { int tc, T, i, j; //freopen("input.txt", "r", stdin); cin >> T; for(tc = 0; tc < T; tc++) { cin>>N; for (i = 1; i <= N; i++) { for (j = 1; j <= N; j++) { cin>>map[i][j]; } } memset(flag, 0x00, 13*sizeof(int)); cost = 0; min_cost = 99999999999; sum = 1; solve(1); cout<<min_cost<<endl; } return 0; }
注意红色代码,不要遗漏