码迷,mamicode.com
首页 > 其他好文 > 详细

hdu4751 最短路+背包dp

时间:2015-05-21 19:35:46      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:

http://acm.hdu.edu.cn/showproblem.php?pid=4571



Problem Description
  Bob gets tired of playing games, leaves Alice, and travels to Changsha alone. Yuelu Mountain, Orange Island, Window of the World, the Provincial Museum etc...are scenic spots Bob wants to visit. However, his time is very limited, he can’t visit them all. 
  Assuming that there are N scenic spots in Changsha, Bob defines a satisfaction value Si to each spot. If he visits this spot, his total satisfaction value will plus Si. Bob hopes that within the limited time T, he can start at spot S, visit some spots selectively, and finally stop at spot E, so that the total satisfaction value can be as large as possible. It‘s obvious that visiting the spot will also cost some time, suppose that it takes Ci units of time to visit spot i ( 0 <= i < N ).
  Always remember, Bob can choose to pass by a spot without visiting it (including S and E), maybe he just want to walk shorter distance for saving time. 
  Bob also has a special need which is that he will only visit the spot whose satisfaction value is strictly larger than that of which he visited last time. For example, if he has visited a spot whose satisfaction value is 50, he would only visit spot whose satisfaction value is 51 or more then. The paths between the spots are bi-directional, of course.
 

Input
  The first line is an integer W, which is the number of testing cases, and the W sets of data are following.
  The first line of each test data contains five integers: N M T S E. N represents the number of spots, 1 < N < 100; M represents the number of paths, 0 < M < 1000; T represents the time limitation, 0 < T <= 300; S means the spot Bob starts from. E indicates the end spot. (0 <= S, E < N)
  The second line of the test data contains N integers Ci ( 0 <= Ci <= T ), which means the cost of time if Bob visits the spot i.
  The third line also has N integers, which means the satisfaction value Si that can be obtained by visiting the spot i ( 0 <= Si < 100 ).
  The next M lines, each line contains three integers u v L, means there is a bi-directional path between spot u and v and it takes L units of time to walk from u to v or from v to u. (0 <= u, v < N, 0 <= L <= T)
 

Output
  Output case number in the first line (formatted as the sample output).
  The second line contains an integer, which is the greatest satisfaction value.
If Bob can’t reach spot E in T units of time, you should output just a “0” (without quotation marks).
 

Sample Input
1 4 4 22 0 3 1 1 1 1 5 7 9 12 0 1 10 1 3 10 0 2 10 2 3 10
 

Sample Output
Case #1: 21
/**
hdu4751  最短路+背包dp
题目大意:给定一个图网络,想要从起点走到终点,可以访问一些点,访问需要耗费一定的时间,每访问一个点都可以得到该点的一个满意值,当然也可以选择路过该点,路过不
          需要时间,那么问题来了:在给定时间内能否从起点走到终点,如果能可以得到的最大花费值是多少?
解题思路:这个题目的意思有很多细节需要揣摩:1,路过点不用花费时间,但也不能得到满意值,2,最后到达终点即可,不一定非要访问终点
          先求出每两个点之间的最短路,然后dp转移。dp的时候注意一点,访问的下一点要比当前点的满意度要高,这就要求我们在算满意度点为i的点的时候,所有满意度
          小于i的点的状态都要已知,所以处理的时候要满意度递增先排个序。。最后值得一提的是一定要注意重边,坑死我了
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=105;
int n,m,s,t,e;
int a[maxn][maxn],dp[maxn][350],Hash[maxn];
struct note
{
    int w,v,id;
    bool operator <(const note &other) const
    {
        return v<other.v;
    }
} p[maxn];
int main()
{
    int T,tt=0;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d%d%d",&n,&m,&t,&s,&e);
        for(int i=0; i<n; i++)
        {
            scanf("%d",&p[i].w);
            p[i].id=i;
        }
        for(int i=0; i<n; i++)
        {
            scanf("%d",&p[i].v);
        }
        sort(p,p+n);
        for(int i=0; i<n; i++)
        {
            Hash[p[i].id]=i;
        }
        for(int i=0; i<=100; i++)
        {
            for(int j=0; j<=100; j++)
            {
                if(i==j)
                    a[i][j]=0;
                else
                    a[i][j]=INF;
            }
        }
        while(m--)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            u=Hash[u],v=Hash[v];
            a[u][v]=min(a[u][v],w);///重边取最小,不写必错,我都快哭了==shit
            a[v][u]=min(a[v][u],w);
        }
        for(int k=0; k<n; k++)
        {
            for(int i=0; i<n; i++)
            {
                if(a[i][k]!=INF)
                {
                    for(int j=0; j<n; j++)
                    {
                        if(a[k][j]!=INF)
                        {
                            a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
                        }
                    }
                }
            }
        }
        s=Hash[s];
        e=Hash[e];
        memset(dp,-1,sizeof(dp));
        for(int i=0; i<n; i++)
        {
            for(int j=p[i].w+a[i][s]; j<=t; j++)
            {
                dp[i][j]=p[i].v;
            }
        }
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<i; j++)
            {
                if(p[i].v==p[j].v)break;
                for(int k=0; k<=t; k++)
                {
                    if(k<a[i][j]+p[i].w)continue;
                    if(dp[j][k-a[i][j]-p[i].w]==-1)continue;
                    dp[i][k]=max(dp[i][k],dp[j][k-a[i][j]-p[i].w]+p[i].v);
                }
            }
        }
        int maxx=0;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<=t; j++)
            {
                if(j+a[i][e]>t)break;
                maxx=max(maxx, dp[i][j]);
            }
        }
        printf("Case #%d:\n%d\n",++tt,maxx);
    }
    return 0;
}
/**
1
4 4 22 0 3
22 22 22 22
5 7 9 12
0 1 10
1 3 10
0 2 10
2 3 10
*/


hdu4751 最短路+背包dp

标签:

原文地址:http://blog.csdn.net/lvshubao1314/article/details/45895805

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!