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");
    }
}

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

时间: 2024-10-12 08:47:35

HUNNU 11568 Interstellar Travel(DP+优先队列)的相关文章

2018 Multi-University Training Contest 3 1007 / hdu6325 Problem G. Interstellar Travel 凸包

Problem G. Interstellar Travel 题意: 给定平面上n个点,起点1 为(0,0),终点 n 为(Xn, 0),其它点的横坐标 0 <Xi<Xn,纵坐标 Xi >=0.每次可以飞到一个横坐标严格更大的点,代价为两个坐标的叉积.求起点到终点总代价最小的飞行路线,并输出字典序最小的路线.2≤n≤200000. Shortest judge solution: 979 bytes 题解: 显然坐标相同的点里只保留编号最小的点最优. 将起点到终点的路径补全为终点往下走到

hdu6325 Interstellar Travel 凸包变形

题目传送门 题目大意: 给出n个平面坐标,保证第一个点和第n个点y值为0,其余点的x坐标都在中间,要从 i 点走到 j 点的要求是 i 点的横坐标严格小于 j 的横坐标,并且消耗的能量是(xi * yj - xj * yi),要求消耗的能量最小(能量可以为负),并且字典序要求最小. 思路: 消耗能量的式子就是两个坐标的叉积,叉积的几何意义就是两个向量对应的平行四边形的面积,但是这个面积会有正负,如果向量 j 在向量 i 的顺时针方向,则这个面积是负的,如果我希望能量最小,那么就尽可能使向量是顺时

ZOJ 3632 ----dp+优先队列

上个礼拜学长讲了优先队列的说.... emmmmmm.... 看着题解敲了一题...先m下. #include<cstring> #include<algorithm> #include<iostream> #include<cmath> #include<cstdio> #include<queue> using namespace std; struct gua { long long v,d; bool operator <

POJ 3162 Walking Race 树形dp 优先队列

http://poj.org/problem?id=3162 题意 :  一棵n个节点的树.wc爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要在这n个距离里取连续的若干天,使得这些天里最大距离和最小距离的差小于M,问怎么取使得天数最多? 每个点的最大距离和之前http://acm.hdu.edu.cn/showproblem.php?pid=2196这道题一样 (就是求每个子树的最长子链,次长子链,然后求经过父亲节点能达到的最大值,比较一

【单调栈】hdu6325 Problem G. Interstellar Travel

从后往前更新,维护一个递减单调栈(队列) 最近很多题都是单调栈... #define _CRT_SECURE_NO_WARNINGS #include<cstdio> #include<algorithm> #include<queue> #include<iostream> //#include<deque> using namespace std; const int maxn = 1e7 + 5; int n, m, k, P, Q, R,

2018 HDU多校第三场赛后补题

2018 HDU多校第三场赛后补题 从易到难来写吧,其中题意有些直接摘了Claris的,数据范围是就不标了. 如果需要可以去hdu题库里找.题号是6319 - 6331. L. Visual Cube 题意: 在画布上画一个三维立方体. 题解: 模拟即可. 代码: #include <bits/stdc++.h> using namespace std; int a, b, c, R, C; char g[505][505]; int main () { int T; cin >>

{POJ}{动态规划}

动态规划与贪心相关: {POJ}{2479}{Maximum Sum} (DP) 摘要: 题意:给定n个数,求两段连续子列的最大和.思路:先从左向右dp,求出一段连续子列的最大和,再从右向左dp,求出两段连续子列的最大和,方法还是挺经典的. {POJ}{1036}{Gansters} (DP) 摘要: 题意:有个伸缩门,门的宽度0~K,每个时间可以伸长或缩短1个单位,有N个流氓,他们在T时刻到达,如果这时门的宽度正好与他们的stoutness相等时,便可获得一定的收入,问最大的收入是多少. 思路

2018 Multi-University Training Contest 3 - HDU Contest

题解: solution Code: A. Ascending Rating #include<cstdio> const int N=10000010; int T,n,m,k,P,Q,R,MOD,i,a[N],q[N],h,t;long long A,B; int main(){ scanf("%d",&T); while(T--){ scanf("%d%d%d%d%d%d%d",&n,&m,&k,&P,&am

2018 Multi-University Training Contest 3

2018 Multi-University Training Contest 2 题解 A - Problem A. Ascending Rating 题目描述:给定一个序列,分别求出所有长度为\(m\)的区间的\(maxrating, count\),对于每个长度为\(m\)的区间,一开始\(maxrating=-1, count=0\),然后从左往右扫,扫到一个大于\(maxrating\)的值时,\(count+1, maxrating=\)那个数. solution 从左往右做,用单调队