hdu 4396 More lumber is required(最短路)

hdu 4396 More lumber is required

Description

“More lumber(木材) is required” When the famous warcrafts player Sky wants to build a Central Town, he finds there is not enough lumber to build his Central Town. So he needs to collect enough lumber. He lets farmer John to do this work.

  There are several Sawmills(锯木厂) have already been built in the world, around them are large forests. Sawmills are connected by bidirectional(双向的) roads (a sawmill can be connected to itself). When he passes a road, he will get 10 lumber and consume(消耗) a certain time. Sky needs K lumber. So John needs collect as least K lumber.

  Sawmills are labeled(有标签的) from 1 to N. John initiates(开始) at Sawmill S. When he finishes his work, Sky gives him another work: arrive at Sawmill T, and build the Central Town. John needs to design his route(按某路线发送) carefully because Sky wants to build this Central Town as early as possible. He turns you for help. Please help him calculate(计算) the minimum(最小的) time he needs to finish this work (collect enough lumber and build the Central Town). If impossible just print -1.

  You can read the Sample Input and Output for more information.

Input

There are multiply test cases, in each test case:

The first line is two integers(整数) N (1<=N<=5000), M (0<=M<=100000) represent the number of sawmills and the number of the roads.

The next M line is three integers A B C (1<=A, B<=N; 1<=C<=100), means there exists a road connected A th sawmill and B th sawmill, and pass this road will cost C time.(The sawmills are labeled from 1 to N).

The last line is three integers S T K (1<=S, T<=N; 0<=K<=500), as mentioned as description.

Output

For each test case, print the result in a single line.

Sample Input

4 4

1 2 1

2 3 2

1 3 100

3 4 1

1 3 50

Sample Output

7

题目大意:有n家伐木场,伐木场之间有m条路径,路径包括路径的起始点和目标点和耗时。然后告诉你起点s和终点t,还有需要的木材数量k。每经过一家伐木场,木材数量加10。现在问,从起点出发,到达终点并收集满k的木材,所需要的最短时间。

解题思路:SPFA。开一个二维d[i][j]数组,记录从起点出发,到达i点,并且收集j的木材所耗费的最小时间,用队列不断维护这个数组就可以了。k有可能不是10的倍数,这个时候要对k进行处理。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <queue>
using namespace std;

typedef long long ll;
const int N = 5005;
const int M = 200005;
const int NN = 505;
const int Lum = 10;
const int INF = 0x3f3f3f3f;
int vis[N][NN], d[N][NN], en;
int head[M];
int n, m, s, t, k;

struct node {
    int to, dis, next;
}edge[M];  

void addEdge(int u,int v,int x) {
    edge[en].to = v;
    edge[en].next = head[u];
    edge[en].dis = x;
    head[u] = en++;  

    edge[en].to = u;
    edge[en].next = head[v];
    edge[en].dis = x;
    head[v] = en++;
}
struct Node{
    int u, m;
};
void SPFA() {
    queue<Node> Q;
    for(int i = 1; i <= n; i++) {
        for (int j = 0; j <= NN; j++) {
            d[i][j] = INF;
            vis[i][j] = 0;
        }
    }
    d[s][0] = 0;
    vis[s][0] = 1;
    Q.push((Node){s, 0});
    while(!Q.empty()) {
        int u = Q.front().u;
        int m = Q.front().m;
        vis[u][m] = 0;
        Q.pop();
        int temp = m + Lum;
        if (temp >= NN) continue;
        if (temp > k) temp = k;
        for(int i = head[u]; i != -1; i = edge[i].next) {
            int v = edge[i].to;
            if(d[u][m] + edge[i].dis < d[v][temp]) {
                d[v][temp] = d[u][m] + edge[i].dis;
                if(!vis[v][temp]) {
                    Q.push((Node){v, temp});
                    vis[v][temp] = 1;
                }
            }
        }
    }
} 

void input() {
    int u, v, c;
    for (int i = 0; i < m; i++) {
        scanf("%d %d %d", &u, &v, &c);
        addEdge(u, v, c);
    }
    scanf("%d %d %d", &s, &t, &k);
}

int main() {
    while (scanf("%d %d", &n, &m) == 2) {
        en = 0;
        memset(head, -1, sizeof(head));
        input();
        if (k % 10) {
            k = 10 * ((k / 10) + 1);
        }
        SPFA();
        if (d[t][k] == INF) {
            printf("-1\n");
        } else printf("%d\n", d[t][k]);
    }
    return 0;
}

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

时间: 2024-11-06 10:59:39

hdu 4396 More lumber is required(最短路)的相关文章

HDU - 4396 More lumber is required (BFS 最短路)

题目大意:有一个需要采集K跟木头,然后到达点T,现在他从S点出发,路上有N个节点,M条边,只要经过1条边,就可以得到10根木头,问需要花费多少时间才能完成任务 解题思路:木头最多只有500根,且每次收集10跟,最多也只需要收集50次就可以,而且节点最多只有5000个,所以直接暴力BFS即可 #include <cstdio> #include <cstring> #include <queue> using namespace std; #define N 5010 #

HDOJ 题目4396 More lumber is required(至少经过k条边的最短路)

More lumber is required Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Total Submission(s): 1392    Accepted Submission(s): 538 Problem Description "More lumber is required" When the famous warcrafts playe

More lumber is required

hdu4396:http://acm.hdu.edu.cn/showproblem.php?pid=4396 题意:一个无向带权图,然后给出起点s,终点e,让你求s到e的最短路径,但是这里的路径有要求的.每经过一条边会得到10单位的财富,这条路径必须得到的财富至少k值. 题解:一开始以为是DP,看了别人的代码,才知道了这就是传说中的二维最短路径.然后学习了一下,其实,就是图上的DP.dist[i][j]表示到达i点得到j个财富的最短路径.然后,利用spfa跑最短路,在这个过程中不断更新dist数

HDU 1596 find the safest road (最短路)

find the safest road Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6973    Accepted Submission(s): 2469 Problem Description XX星球有很多城市,每个城市之间有一条或多条飞行通道,但是并不是所有的路都是很安全的,每一条路有一个安全系数s,s是在 0 和 1

HDU 4063 线段与圆相交+最短路

Aircraft Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 980    Accepted Submission(s): 228 Problem Description You are playing a flying game. In the game, player controls an aircraft in a 2D-

HDU 2066-一个人的旅行(最短路Dijkstra)

一个人的旅行 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 19349    Accepted Submission(s): 6763 Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰

hdu 4885 TIANKENG’s travel (最短路+判断三点共线)

TIANKENG's travel Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 408    Accepted Submission(s): 100 Problem Description TIANKENG has get a driving license and one day he is so lucky to find a

HDU 3416 Marriage Match IV(最短路+网络流之最大流)

题目地址:HDU 3416 这道题WA了一天半...最终才发现是我一直习惯性的将isap的表示上界的变量直接表示成sink+1了...但是在这道题里汇点sink不一定是最后一个点...sad... 这题可以有两种方法做,一种是求两次最短路,d1表示所有点到源点的最短距离,再求一次用d2表示所有点到汇点的最短距离.然后根据公式d1[u]+d2[v]+w==d1[sink]判断是否属于最短路中的一条边. 还有一种是只求一次最短路,直接用d[v]==d[u]+w来判断是否是可以到达源点的最短路,如果可

HDU 1428 漫步校园 特殊的最短路

HDU 1428 漫步校园 特殊的最短路 题意 这里需要读懂题意中的一句话"另外,他考虑从A区域到B区域仅当存在一条从B到机房的路线比任何一条从A到机房的路线更近(否则可能永远都到不了机房了-)." 这句话的意思是从(1, 1)到(n, n)的所有路径中,只选择距离最短的路径,并输出最短路径的条数.就是我们找出最短距离后,看看有多少条路到达目的地是最短距离. 解题思路 从题意我们也就知道了,我们需要找出每个点到目的地的最短路是多少.这里我们最先想到的就是一些最短路的算法了,比如Dijk