HDU3768 Shopping(状态压缩DP+spfa)旅行商问题

Shopping

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 577    Accepted Submission(s): 197

Problem Description

You have just moved into a new apartment and have a long list of items you need to buy. Unfortunately, to buy this many items requires going to many different stores. You would like to minimize the amount of driving necessary to buy
all the items you need.

Your city is organized as a set of intersections connected by roads. Your house and every store is located at some intersection. Your task is to find the shortest route that begins at your house, visits all the stores that you need to shop at, and returns to
your house.

Input

The first line of input contains a single integer, the number of test cases to follow. Each test case begins with a line containing two integers N and M, the number of intersections and roads in the city, respectively. Each of these
integers is between 1 and 100000, inclusive. The intersections are numbered from 0 to N-1. Your house is at the intersection numbered 0. M lines follow, each containing three integers X, Y, and D, indicating that the intersections X and Y are connected by
a bidirectional road of length D. The following line contains a single integer S, the number of stores you need to visit, which is between 1 and ten, inclusive. The subsequent S lines each contain one integer indicating the intersection at which each store
is located. It is possible to reach all of the stores from your house.

Output

For each test case, output a line containing a single integer, the length of the shortest possible shopping trip from your house, visiting all the stores, and returning to your house.

Sample Input

1
4 6
0 1 1
1 2 1
2 3 1
3 0 1
0 2 5
1 3 5
3
1
2
3

Sample Output

4

Source

University of Waterloo Local Contest 2010.07.10

题意:给出n个点,m条路,s(1<=s<=10)个店位于n个地方,现在要求从0点出发走完所有的店的最小花费。

解题:先求出店与店之间的最短路,包括出发点0,然后就是状态压缩dp。

#include<stdio.h>
#include<queue>
#include<vector>
using namespace std;
#define mov(a) (1<<(a))
const int N = 100005;
const int inf = 99999999;
struct EDG{
    int v,c;
};

int dis[N],inq[N],mark[N],n,road[15][15],dp[mov(12)][12];
vector<EDG>mapt[N];

void spfa(int s)
{
    queue<int>q;
    for(int i=0;i<=n;i++)
        dis[i]=inf,inq[i]=0;
    dis[s]=0;
    q.push(s);
    while(!q.empty())
    {
        s=q.front(); q.pop();
        inq[s]=0;
        int k=mapt[s].size();
        for(int i=0;i<k;i++)
        {
            int v=mapt[s][i].v;
            if(dis[v]>dis[s]+mapt[s][i].c)
            {
                dis[v]=dis[s]+mapt[s][i].c;
                if(inq[v]==0)
                    inq[v]=1,q.push(v);
            }
        }
    }
}
int main()
{
    int t,m,s,a,b,store[15];
    EDG ss;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
            mapt[i].clear(),mark[i]=-1;
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&ss.c);
            ss.v=b; mapt[a].push_back(ss);
            ss.v=a; mapt[b].push_back(ss);
        }
        scanf("%d",&s);
        store[0]=0; mark[0]=0; s++;
        for(int i=1;i<s;i++)
        {
            scanf("%d",&store[i]); mark[store[i]]=i;
        }

        for(int i=0;i<s;i++)//求出店与店之间的最短路
        {
            spfa(store[i]);
            for(int j=0;j<n;j++)
            if(mark[j]>=0)
                road[i][mark[j]]=dis[j];
        }

        for(int sta=0;sta<mov(s);sta++)
            for(int i=0;i<s;i++)
            dp[sta][i]=inf;
        dp[1][0]=0;
        for(int sta=1;sta<mov(s);sta++)
        for(int i=0;i<s;i++)
        if(dp[sta][i]!=inf)
        {
            for(int j=1;j<s;j++)
            if((sta&mov(j))==0)
            {
                if(dp[sta|mov(j)][j]>dp[sta][i]+road[i][j])
                    dp[sta|mov(j)][j]=dp[sta][i]+road[i][j];
            }
        }
        int ans=inf;
        for(int i=0;i<s;i++)
        if(dp[mov(s)-1][i]+road[i][0]<ans)
        ans=dp[mov(s)-1][i]+road[i][0];

        printf("%d\n",ans);
    }
}
时间: 2024-10-10 16:34:29

HDU3768 Shopping(状态压缩DP+spfa)旅行商问题的相关文章

HDU 4085 Peach Blossom Spring 斯坦纳树 状态压缩DP+SPFA

状态压缩dp+spfa解斯坦纳树 枚举子树的形态 dp[i][j] = min(dp[i][j], dp[i][k]+dp[i][l]) 其中k和l是对j的一个划分 按照边进行松弛 dp[i][j] = min(dp[i][j], dp[i'][j]+w[i][j])其中i和i'之间有边相连 #include <cstdio> #include <cstring> #include <queue> using namespace std; const int maxn

Codeforces Round #108 (Div. 2)——状态压缩DP+spfa+dfs——Garden

Vasya has a very beautiful country garden that can be represented as an n × m rectangular field divided into n·m squares. One beautiful day Vasya remembered that he needs to pave roads between k important squares that contain buildings. To pave a roa

Victor and World(spfa+状态压缩dp)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 Victor and World Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Others)Total Submission(s): 958    Accepted Submission(s): 431 Problem Description After trying hard fo

动态规划之状态压缩dp入门

状态压缩动态规划(简称状压dp)是另一类非常典型的动态规划,通常使用在NP问题的小规模求解中,虽然是指数级别的复杂度,但速度比搜索快,其思想非常值得借鉴. 为了更好的理解状压dp,首先介绍位运算相关的知识. 1.'&'符号,x&y,会将两个十进制数在二进制下进行与运算,然后返回其十进制下的值.例如3(11)&2(10)=2(10). 2.'|'符号,x|y,会将两个十进制数在二进制下进行或运算,然后返回其十进制下的值.例如3(11)|2(10)=3(11). 3.'^'符号,x^y

[转]状态压缩dp(状压dp)

状态压缩动态规划(简称状压dp)是另一类非常典型的动态规划,通常使用在NP问题的小规模求解中,虽然是指数级别的复杂度,但速度比搜索快,其思想非常值得借鉴. 为了更好的理解状压dp,首先介绍位运算相关的知识. 1.'&'符号,x&y,会将两个十进制数在二进制下进行与运算,然后返回其十进制下的值.例如3(11)&2(10)=2(10). 2.'|'符号,x|y,会将两个十进制数在二进制下进行或运算,然后返回其十进制下的值.例如3(11)|2(10)=3(11). 3.'^'符号,x^y

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反

HDU1565(状态压缩dp)

方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8170    Accepted Submission(s): 3095 Problem Description 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数

HDU 3001【状态压缩DP】

题意: 给n个点m条无向边. 要求每个点最多走两次,要访问所有的点给出要求路线中边的权值总和最小. 思路: 三进制状态压缩DP,0代表走了0次,1,2类推. 第一次弄三进制状态压缩DP,感觉重点是对数据的预处理,利用数组分解各个位数,从而达到类似二进制的目的. 然后就是状态的表示,dp[s][i]表示状态s时到达i的最优值. 状态转移也一目了然,不废话. #include<stdio.h> #include<string.h> #include<algorithm> u

poj 3311 Hie with the Pie(状态压缩dp)

Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can afford to hire only one driver to do the deliveries. He will wait for 1 or more (up to 10) orders to be