HDU 5418 Victor and World(狀壓dp、floy最短路)

Victor and WorldTime Limit:2000MS    Memory Limit:131072KB    64bit IO Format:%I64d & %I64u

Description

After trying hard for many years, Victor has finally received a pilot license. To have a celebration, he intends to buy himself an airplane and fly around the world. There are   countries on the earth, which are numbered from   to  . They are connected by   undirected flights, detailedly the  -th flight connects the    -th and the    -th country, and it will cost Victor's airplane     L fuel if Victor flies through it. And it is possible for him to fly to every country from the first country.

Victor now is at the country whose number is  , he wants to know the minimal amount of fuel for him to visit every country at least once and finally return to the first country.

Input

The first line of the input contains an integer  , denoting the number of test cases.
In every test case, there are two integers   and   in the first line, denoting the number of the countries and the number of the flights.

Then there are   lines, each line contains three integers    ,     and    , describing a flight.

 .

 .

 .

   .

     .

Output

Your program should print   lines : the  -th of these should contain a single integer, denoting the minimal amount of fuel for Victor to finish the travel.

Sample Input

1
3 2
1 2 2
1 3 3

Sample Output

10

首先用Folyd求出任意兩點間的最短路。

然後令dp[i][S]表示訪問情況爲S,最後訪問i國家的最小花費。

轉移方程爲dp[i][S|(1<<i-1)]=min(dp[j][S]+mp[j][i])(對於所有的j)(i,j滿足集合S包含j不包含i,S是用二進制表示的集合)

mp[j][i]表示從j到i的最短路。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int map[17][17];
int dp[17][1<<17];
int main()
{
    int t,n,m;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&n,&m);
        int x,y,d;
        memset(map,0x3f,sizeof(map));
        for(int i=0;i<m;i++){
            scanf("%d %d %d",&x,&y,&d);
            map[y][x]=map[x][y]=min(map[x][y],d);
        }
        for(int i=0;i<=n;i++) map[i][i]=0;
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
              for(int j=1;j<=n;j++)
                map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
        memset(dp,0x3f,sizeof(dp));
        dp[1][1]=0;
        for(int i=1;i<=((1<<n)-1);i++)///zhuang tai
        {
            for(int j=1;j<=n;j++)///qi dian
            {
                if(i&(1<<(j-1)))
                    for(int k=1;k<=n;k++)///zhong dian
                    {
                        if((i &(1 <<(k -1))) == 0)
                            dp[k][i|(1<<(k-1))]=min(dp[k][i|(1<<(k-1))],dp[j][i]+map[j][k]);
                    }
            }
        }
        int ans=0x3f3f3f3f;
        for(int i=2;i<=n;i++)
            ans=min(ans,dp[i][(1<<n)-1]+map[i][1]);
        if(n==1) ans=0;
        printf("%d\n",ans);
    }
    return 0;
}



發佈了106 篇原創文章 · 獲贊 5 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章