Repository navigation
Expand file tree
/
Copy pathTSP.cpp
More file actions
119 lines (113 loc) · 4.03 KB
/
Copy pathTSP.cpp
File metadata and controls
119 lines (113 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <bits/stdc++.h>
using namespace std;
using namespace std::chrono;
namespace TSP {
const int MAXN = 30;
long long eds [ MAXN ] [ MAXN ] ;
long long tmp [MAXN];
struct List {
struct Node {
Node * nx = nullptr;
int val ;
Node ( int val ) : val ( val ) { nx = nullptr ; }
} *begin = nullptr ;
} ;
long long max_ans = 1e17 + 10;
long long get_MST ( long long on ) {
long long mst = 0;
memset ( tmp , 63,sizeof tmp );
long long cc = on & - on ;
on ^= cc ;
for ( int i = 0;i<MAXN;i++ ) tmp[i] = min ( tmp[i],eds[i][cc] );
while ( on ) {
pair<long long ,int > mn = { 1e9+7,-1 };
for ( long long se = on; se ; se^=se&-se )
mn = min ( mn , { tmp [ __builtin_ctzll ( se ) ] , __builtin_ctzll ( se ) } ) ;
mst += mn.first ;
for ( int i = 0;i<MAXN;i++ ) tmp[i] = min ( tmp[i],eds[i][mn.second] );
on ^= 1LL << mn.second ;
}
return mst;
}
void backtrack ( long long now,int sz,int on ,int st,List list) {
if ( sz == 1 ) {
max_ans = min ( max_ans , now + eds [ on ] [ list.begin -> val ] + eds [ st ] [ list.begin -> val ] );
// max_ans = max ( max_ans , now + eds [ on ] [ list.begin -> val ] + eds [ st ] [ list.begin -> val ] );
return ;
}
List :: Node * it = list . begin ;
List :: Node * it1 = list.begin,*it2;long long mx = 1e17+ 1;
long long mxx = 1e17 +10;
while ( it1 != nullptr )
{
it2 = it1 -> nx ;
mxx = min ( mxx , eds[on ][ it->val ] );
while ( it2 != nullptr ) mx = min ( mx , eds[it1->val][it2->val] ) ,it2 = it2->nx;
it1 = it1 -> nx;
}
if ( sz * mx + mxx >= max_ans ) return ;
List ls ; ls . begin = list . begin -> nx ;
backtrack ( now + eds [ on ] [ list . begin -> val ] , sz-1,list.begin->val,st,ls ) ;
List::Node *prv = ls . begin ; it = it -> nx;
while ( it != nullptr ) {
prv -> nx = it -> nx;
backtrack ( now + eds [ on ] [ it -> val ], sz -1 , it -> val , st, list );
prv -> nx = it;
it = it -> nx;
}
}
void backtrack (long long now,int on,int st,long long seen ) {
if ( __builtin_popcountll ( seen ) == 1 ) {
max_ans = min ( max_ans , now + eds[on][__builtin_ctzll ( seen )] + eds[st][__builtin_ctzll ( seen ) ] ) ;
// max_ans = max ( max_ans , now + eds[on][__builtin_ctzll ( seen )] + eds[st][__builtin_ctzll ( seen ) ] ) ;
return ;
}
long long s2 = seen,s1 = seen;
long long mx = 1e17+ 10 ,mx2 = 1e17 - 10;
for ( long long sw = seen; sw ; sw ^= sw&-sw )
mx2 = min ( mx2, eds [ on ] [ __builtin_ctzll ( sw ) ] ) ;
if ( now + get_MST ( seen /*| ( 1<< on )*/ ) >= max_ans ) return ;
for ( long long ss = seen ; ss ; ss ^= ss&-ss )
backtrack ( now + eds [ on ] [ __builtin_ctzll ( ss ) ] , __builtin_ctzll ( ss ) , st, seen ^ ( ss & - ss ) ) ;
}
} ;
int main ( ) {
using namespace TSP ;
int n;
#ifndef Input
scanf ( "%d" , &n ) ;
for ( int i = 0;i<n;i++ )
for ( int j = 0;j<n;j++ )
scanf ( "%d" , TSP::eds[i] + j ) ;
#else
n = random ( ) % 23;
cout << n << endl;
for ( int i = 0;i<n;i++ )
for ( int j = i + 1;j<n;j++ )
TSP::eds[i][j] = TSP::eds[j][i] = random () % 1000 ;
for ( int i = 0;i<n;i++ ,cout << endl)
for ( int j = 0;j<n;j++ )
cout << TSP::eds[i][j] << " " ;
#endif
/*
List ls ;ls . begin = new List :: Node ( 1 );
List::Node *it = ls . begin ;
for ( int i = 2;i<n;i++ )
{
it-> nx = new List :: Node ( i );
it = it -> nx;
}*/
TSP :: max_ans = 1e17+6.66;
high_resolution_clock::time_point t1 = high_resolution_clock::now();
backtrack ( 0,0,0,( 1LL << n ) - 2 ) ;
high_resolution_clock::time_point t2 = high_resolution_clock::now();
auto dur1 = duration_cast < milliseconds > (t2 - t1 ) .count ();
cout << dur1 << " " << TSP:: max_ans << endl;
/* TSP :: max_ans = 1e17+6.6;
t1 = high_resolution_clock::now();
backtrack ( 0,n-1,0,0,ls );
t2 = high_resolution_clock::now();
auto dur2 = duration_cast <milliseconds > ( t2 - t1 ) .count () ;
cout << dur2 << " " << TSP :: max_ans << endl;*/
return 0;
}