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 }

 

posted on 2015-08-24 15:16  蜘蛛侦探  阅读(404)  评论(0编辑  收藏  举报