HDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法 求 玈行商有关问题)经典

HDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法 求 玈行商问题)经典

Victor and World

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Others)
Total Submission(s): 174    Accepted Submission(s): 79


Problem 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 nHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典 countries on the earth, which are numbered from 1HDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典 to nHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典. They are connected by mHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典 undirected flights, detailedly the iHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典-th flight connects the uHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典iHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典HDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典-th and the vHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典iHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典HDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典-th country, and it will cost Victor's airplane wHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典iHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典HDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典 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 1HDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典, 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 THDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典, denoting the number of test cases.
In every test case, there are two integers nHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典 and mHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典 in the first line, denoting the number of the countries and the number of the flights.

Then there are mHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典 lines, each line contains three integers uHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典iHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典HDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典, vHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典iHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典HDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典 and wHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典iHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典HDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典, describing a flight.

1T20HDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典.

1n16HDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典.

1m100000HDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典.

1wHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典iHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典100HDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典.

1uHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典iHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典,vHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典iHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典nHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典.
 

Output
Your program should print THDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典 lines : the iHDU 5418 Victor and World(状态压缩路径DP或+floyd 两种方法  求 玈行商有关问题)经典-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
 

Source

BestCoder Round #52 (div.2) 

题意:有n个点m条无向边,现在从1点出发最后又回到1点,必须经过所有的点。

方法一:状态压缩DP +floyd。(500+MS)AC

#include<stdio.h>
#include<string.h>
const int INF = 1<<30 ;

int dp[1<<17][20];
int n,m,u,v,w,mp[20][20] ;
void floyd()
{
    for(int e=0; e<n; e++)
    for(int i=0; i<n; i++)
    if(i!=e&&mp[i][e]!=INF)
    {
        for(int j=0; j<n; j++)
            if(mp[i][j]>mp[i][e]+mp[e][j])
              mp[i][j] = mp[i][e]+mp[e][j];
    }
}
int main()
{

    int T ;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0; i<(1<<n); i++)
            for(int j=0; j<=n; j++)
              dp[i][j] = INF;

        for(int i=0; i<=n; i++)
        {
            for(int j=0; j<=n; j++)
                 mp[i][j] = INF;
            mp[i][i]=0;
        }

        while(m--)
        {
            scanf("%d%d%d",&u,&v,&w);
            u--; v--;
            if(mp[u][v]>w)
                mp[u][v]=mp[v][u]=w;
        }
        floyd();
        dp[1][0] = 0 ;
        for(int s=1; s<(1<<n); s++)
        for(int i=0; i<n; i++)
        if(dp[s][i]!=INF)
        {
            for(int j=0; j<n; j++)
                if(dp[s|(1<<j)][j]>dp[s][i]+mp[i][j])
                    dp[s|(1<<j)][j] = dp[s][i]+mp[i][j] ;
        }
        
        int ans = INF;
        for(int i=0; i<n; i++)
            if(ans > dp[(1<<n)-1][i]+mp[i][0])
                ans = dp[(1<<n)-1][i]+mp[i][0] ;
        printf("%d\n",ans);
    }
}


方法二:状态压缩DP  (900+MS)AC

#include<stdio.h>
#include<string.h>
const int INF = 1<<30 ;

int dp[1<<17][20];
int n,m,u,v,w,mp[20][20] , kk[1<<17];

int main()
{

    int T ;
    for(int i=0; i<(1<<16); i++)
    {
        kk[i]=0;
        for(int j=0; j<=16; j++)
            if(i&(1<<j))
              kk[i]++;
    }
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0; i<(1<<n); i++)
            for(int j=0; j<=n; j++)
              dp[i][j] = INF;

        for(int i=0; i<=n; i++)
            for(int j=0; j<=n; j++)
                 mp[i][j] = INF;
        while(m--)
        {
            scanf("%d%d%d",&u,&v,&w);
            u--; v--;
            if(mp[u][v]>w)
                mp[u][v]=mp[v][u]=w;
        }
        dp[1][0] = 0 ;
        for(int s=1; s<(1<<n); s++)
        for(int k=0; k<=kk[s]; k++)
        for(int i=0; i<n; i++)
        if(dp[s][i]!=INF)
        {
            for(int j=0; j<n; j++)
                if(dp[s|(1<<j)][j]>dp[s][i]+mp[i][j])
                    dp[s|(1<<j)][j] = dp[s][i]+mp[i][j] ;
        }
        printf("%d\n",dp[(1<<n)-1][0]);
    }
}


版权声明:本文为博主原创文章,未经博主允许不得转载。