http://acm.hdu.edu.cn/showproblem.php?pid=5418
题目大意是城市的编号是1到n,给出m条路线,表示从a城市飞到b城市飞机要耗多少油,最后问飞机从1出发飞过所有的的城市最后再回到1最少耗多少油(数据保证至少存在一条这样的路),
要考虑的问题是满足全部连通和保证最短,最短好说,用弗洛伊德或者迪杰特斯拉,至于这个全部连通,一下子连想到了之前的状压搜索,用二进制保存是否经过所有的点,最后整理一下就是先
用弗洛伊德求出每从起点1到各个点的最短距离,然后哈密顿算法进行全连通,找出最小的油耗
code
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #define inf 0x3f3f3f3f 5 using namespace std; 6 int min(int x,int y) 7 { 8 if (x<y) return x; 9 else return y; 10 } 11 int map[20][20],dis[20][1<<17]; 12 int main() 13 { 14 int t,m,i,j,a,b,c,k,mn,ans,n; 15 while (~scanf("%d",&t)) 16 { 17 while (t--) 18 { 19 scanf("%d %d",&n,&m); 20 for (i=1;i<=n;i++) 21 { 22 for (j=1;j<=n;j++) 23 { 24 map[i][j]=inf; 25 if (i==j) map[i][j]=0; 26 } 27 } 28 while (m--) 29 { 30 scanf("%d %d %d",&a,&b,&c); 31 if (map[a][b]>c) 32 map[a][b]=map[b][a]=c; 33 } 34 for (k=1;k<=n;k++){ //最短路 35 for (i=1;i<=n;i++){ 36 for (j=1;j<=n;j++) 37 map[i][j]=min(map[i][j],map[i][k]+map[k][j]); 38 } 39 } 40 memset(dis,inf,sizeof(dis)); 41 dis[1][1]=0; 42 for (i=1;i<(1<<n);i++){ 43 for (j=1;j<=n;j++){ 44 if ((i&(1<<(j-1)))!=0){ 45 for (k=1;k<=n;k++) 46 { 47 if ((i&(1<<(k-1)))==0){ 48 ans=(i|(1<<(k-1))); 49 dis[k][ans]=min(dis[k][ans],dis[j][i]+map[j][k]); 50 } 51 } 52 } 53 } 54 } 55 if (n==1) 56 { 57 printf("0\n"); 58 continue; 59 } 60 mn=inf; 61 for (i=2;i<=n;i++) 62 mn=min(mn,dis[i][(1<<n)-1]+map[1][i]); 63 printf("%d\n",mn); 64 } 65 } 66 return 0; 67 }