HUNNU 11568 Interstellar Travel(DP+优先队列)

Interstellar Travel
Time Limit: 1000ms, Special Time Limit:2500ms,Memory Limit:65536KB
Total submit users: 2, Accepted users:1
Problem 11568 : No special judgement
Problem description
  In A.D. 3014, scientists find that wormhole can be used for interstellar traveling. By building a wormhole and traveling through it, spaceship can move from one point in time and space to another point in time and space instantaneously. But it will cost a large amount of energy.

Figure 1 Traveling through wormhole
The Hope's captain, Joseph Burnett, is working on a particular mission of geologic exploration of the Plant T. Now, his spaceship stays on Plant S. It has no energy and needs recharge. The Captain Burnett lists all wormholes that his spaceship can build between all known plants. He needs to compute whether to transfer from these plant(s) and recharge there or build a wormhole from Plant S to Plant T directly. The reason is that the price of energy is different on different plants. For example, on plant DSB945, the price of energy is 47 GUD (General Universe Dollar) per Bronto (a unit of energy) while on plant ZJT116, the price is only 16 GUD per Bronto. Given the price of every known plants, and list of wormholes that the spaceship can build, The Captain Burnett has to plan the route in detail. He wants to travel to Plant T with minimum cost of money (General Universe Dollar).
Remember these two facts: the spaceship can’t recharge energy beyond its limit of maximum energy; if the energy of building a wormhole is beyond that the spaceship loads, the spaceship can’t build this wormhole.
Input
  There are multiple test cases.
The first line contains five integers: N (2 <= N <= 100) , M (1 <= M <= 200), L (1 <= L <= 100), S (1 <= S <= N), T (1 <= T <= N, T ≠ S). N is the number of known plants. M is the number of wormholes the spaceship can build. L is the limit of maximum energy, which means the spaceship can load at most L Bronto energy. The Captain Burnett starts at Plant S and Plant T is his destination.
The second line contains N integers Pi (1 <= Pi <= 1000). They are price of energy in Plant 1~N.
M lines follows. Each line contains three integers: U (1 <= U <= N), V (1 <= V <= N, V ≠ U), E (1 <= E <= L). It means it will cost the spaceship E Bronto energy to build a wormhole from Plant U to Plant V or from Plant V to Plant U.
Output
  If the spaceship can reach Plant T, output the minimum cost of money. Otherwise, output “Unreachable” (without quotation marks).
Sample Input
3 3 100 1 3
10 5 7
1 2 10
2 3 10
1 3 16
4 4 100 1 4
17 24 71 3
1 2 66
2 4 100
1 3 47
3 4 100
3 1 100 1 3
2 3 5
1 2 100
Sample Output
150
3284
Unreachable
Problem Source
  2014哈尔滨理工大学秋季训练赛
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
const int N = 105 ;
const int INF = 1<<30;
struct NODE{
    int u,L,cost;
    friend bool operator<(NODE aa,NODE bb){
        return aa.cost>bb.cost;
    }
};
struct EDG{
    int to,next,L;
}edg[N<<3];
int eid , head[N] ;

void addEdg(int u,int v,int L){
    edg[eid].to=v; edg[eid].next=head[u] ;
    edg[eid].L=L; head[u]=eid++;

    edg[eid].to=u; edg[eid].next=head[v] ;
    edg[eid].L=L; head[v]=eid++;
}
int dp[N][N]  , p[N]; // dp[ 点 ] [ 剩于油量 ] :最少花费 
void init()
{
    eid=0;
    memset(head,-1,sizeof(head));
    for(int i=1; i<N; i++)
        for(int j=0; j<N; j++)
        dp[i][j]=INF;
}

int bfs(int vs , int vt , int n,int L)
{
    priority_queue<NODE>q;
    NODE now,pre;
    for(int i=1; i<=L; i++)
    {
        now.u=vs; now.cost=i*p[vs]; now.L=i;
        dp[vs][i]=now.cost;
        q.push(now);
    }
    while(!q.empty()){
        pre=q.top(); q.pop();
        if(dp[pre.u][pre.L]<pre.cost)continue;
        if(pre.u==vt) return pre.cost;
        for(int i=head[pre.u]; i!=-1; i=edg[i].next){
            if(pre.L<edg[i].L)continue;
            int v=edg[i].to;
            int lft=pre.L-edg[i].L;
            for(int j=lft; j<=L; j++ )
            if(dp[v][j]>pre.cost+(j-lft)*p[v]){
                dp[v][j] = pre.cost+(j-lft)*p[v];
                now.u=v; now.L=j; now.cost=dp[v][j];
                q.push(now);
            }
        }
    }
    return -1;
}
int main()
{
    int n,m,L,vs,vt , u , v, c;
    while(scanf("%d%d%d%d%d",&n,&m,&L,&vs,&vt)>0)
    {
        init();
        for(int i=1; i<=n; i++)
            scanf("%d",&p[i]);//在每个点补充的每升油的单价
        while(m--){
            scanf("%d%d%d",&u,&v,&c); //当前路(无向)的耗油量c
            addEdg(u , v , c);
        }
        int ans = bfs(vs , vt ,n ,L);
        if(ans!=-1)
            printf("%d\n",ans);
        else
            printf("Unreachable\n");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值