hdu 4571 Travel in time 最短路+dp

来源:互联网 发布:手机淘宝点购买没反应 编辑:程序博客网 时间:2024/06/01 23:45

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 isstrictly 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 C i ( 0 <= C i <= 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
14 4 22 0 31 1 1 15 7 9 120 1 101 3 100 2 102 3 10
Sample Output
Case #1:21

n个景点,m条路,总时间t,起始城市s,终点城市e,接下来给出浏览各个城市的时间,然后给出各个城市浏览后的满意程度。然后是m条路的信息。要求选择浏览方式,使得总的满意程度最大,经过一个城市可以选择不去浏览(包括s,e),注意题目要求当前浏览城市的满意度一定要比前一个浏览城市的满意度高,并且最终要回到城市e

1.由于在浏览城市的时间与城市之间路程的差异,有时候选择不浏览所选路径中的某些节点所能获得的满意度更高,所以首先我们需要预处理一下任意两个景点之间的最短路
2.用dp,dp[i][j]表示的是当前是第i个景点所用时间为j的情况下的最大满意度

ac代码:

#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#define INF 0x1f1f1f1fusing namespace std;int n,m,t,s,e;struct node{    int id;    int c;    int myd;} data[105];int phi[105][105];int dp[105][305];bool cmp(node a,node b){    return a.myd<b.myd;}void floyd(){    for(int k=0; k<n; k++)    {        for(int i=0; i<n; i++)        {            for(int j=0; j<n; j++)            phi[i][j]=min(phi[i][k]+phi[k][j],phi[i][j]);        }    }}int slove(){    int sum=0;    memset(dp,-1,sizeof(dp));    for(int i=0; i<n; i++)    {        if(data[i].c+phi[s][data[i].id]<=t)        {            dp[data[i].id][data[i].c+phi[s][data[i].id]]=data[i].myd;        }    }    for(int i=1; i<n; i++)    {        for(int j=t; j>=0; j--)        {            for(int k=0; k<i; k++)            {                if(data[i].c+phi[data[k].id][data[i].id]<=j&&data[i].myd>data[k].myd&&dp[data[k].id][j-data[i].c-phi[data[k].id][data[i].id]]!=-1)                    dp[data[i].id][j]=max(dp[data[i].id][j],dp[data[k].id][j-data[i].c-phi[data[k].id][data[i].id]]+data[i].myd);            }        }    }    for(int i=0; i<n; i++)    {        for(int j=0; j<=300; j++)        {            if(t-j>=phi[data[i].id][e])                sum=max(sum,dp[data[i].id][j]);        }    }    return sum;}int main(){    int t1,p=0;    cin>>t1;    while(t1--)    {        p++;        cin>>n>>m>>t>>s>>e;        for(int i=0; i<n; i++)            data[i].id=i;        for(int i=0; i<n; i++)            scanf("%d",&data[i].c);        for(int i=0; i<n; i++)            scanf("%d",&data[i].myd);        sort(data,data+n,cmp);        int u,v,w;        for(int i=0; i<n; i++)        {            for(int j=0; j<n; j++)            {                if(i==j)                    phi[i][j]=0;                else                    phi[i][j]=INF;            }        }        for(int i=0; i<m; i++)        {            scanf("%d%d%d",&u,&v,&w);            phi[u][v]=phi[v][u]=min(phi[u][v],w);        }        floyd();        printf("Case #%d:\n",p);        if(phi[s][e]>t)        {            printf("0\n");            continue;        }        int sum=slove();        cout<<sum<<endl;    }    return 0;}