floyed first 设f[i][S]表示取到了S集合中的所有点(不一定是经过的所有点),最后停在了i的最优值。
初始就f[i][{i}] = dis[1][i]
状态转移直接转就好了
f[i][S] + dis[i][j] -> f[j][S + {j}]其中 i 属于 S,1 <= j <= n
设tim[S] = min{f[i][S]}
答案就取到
ans = min{max{tim[S],tim[Cs]}}
1 #include <map> 2 #include <queue> 3 #include <cstdio> 4 #include <cstring> 5 #include <climits> 6 #include <algorithm> 7 using namespace std; 8 inline void read(int &x){ 9 x=0;char ch;bool flag = false; 10 while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true; 11 while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x; 12 } 13 inline int cat_min(const int &a,const int &b){return a<b ? a:b;} 14 inline int cat_max(const int &a,const int &b){return a>b ? a:b;} 15 inline int cat_abs(const int &x){return x < 0 ? -x : x;} 16 const int maxn = 19; 17 const int maxs = (1<<19) + 1; 18 int dis[maxn][maxn],n,f[maxn][maxs],tim[maxs]; 19 inline void init(){ 20 memset(dis,0x3f,sizeof dis); 21 memset(f,0x3f,sizeof f); 22 memset(tim,0x3f,sizeof tim); 23 } 24 void floyed(){ 25 for(int i=1;i<=n;++i){ 26 dis[i][i] = 0; 27 for(int j=1;j<=n;++j){ 28 if(i == j) continue; 29 for(int k=1;k<=n;++k){ 30 dis[i][j] = cat_min(dis[i][j], 31 dis[i][k] + dis[k][j]); 32 } 33 } 34 }return; 35 } 36 map<int,int>ma; 37 int main(){ 38 39 int m;read(n);read(m); 40 init(); 41 for(int i=1,u,v,d;i<=m;++i){ 42 read(u);read(v);read(d); 43 if(dis[u][v] > d) dis[u][v] = dis[v][u] = d; 44 } 45 floyed(); 46 for(int i=0;i<=18;++i) ma[1<<i] = i+1; 47 for(int i=1;i<=n;++i) f[i][(1<<0) | (1<<(i-1))] = dis[1][i]; 48 for(int i=0,x=0;i<(1<<n);x = (++i) ){ 49 while(x){ 50 int p = ma[x&-x];x -=x&-x; 51 for(int j=1;j<=n;++j){ 52 if( f[j][i | (1<<(j-1))] > f[p][i] + dis[p][j]){ 53 f[j][i | (1<<(j-1))] = f[p][i] + dis[p][j]; 54 } 55 } 56 } 57 } 58 for(int i=0,x=0;i<(1<<n);x = (++i) ){ 59 while(x){ 60 int p = ma[x & -x];x -= x&-x; 61 tim[i]=cat_min(tim[i],f[p][i]); 62 } 63 } 64 int ans = 0x7f7f7f7f; 65 for(int i=0;i<(1<<n);++i){ 66 ans = cat_min(ans,cat_max(tim[i], 67 tim[1 | (( (1 << n)-1 )^i) ])); 68 }printf("%d\n",ans); 69 //getchar();getchar(); 70 fclose(stdin);fclose(stdout); 71 return 0; 72 }