SOJ3423: Revamping Trails--(最短路 + 动态规划)

来源:互联网 发布:linux编辑hosts 编辑:程序博客网 时间:2024/06/05 17:05
Description
Farmer John dutifully checks on the cows every day. He traversessome of the M (1 <= M <= 50,000) trails conveniently numbered 1..Mfrom pasture 1 all the way out to pasture N (a journey which isalways possible for trail maps given in the test data). The N (1<= N <= 10,000) pastures conveniently numbered 1..N on Farmer John'sfarm are currently connected by bidirectional dirt trails.  Eachtrail i connects pastures P1_i and P2_i (1 <= P1_i <= N; 1 <= P2_i<= N) and requires T_i (1 <= T_i <= 1,000,000) units of time totraverse.He wants to revamp some of the trails on his farm to save time onhis long journey. Specifically, he will choose K (1 <= K <= 20)trails to turn into highways, which will effectively reduce thetrail's traversal time to 0. Help FJ decide which trails to revampto minimize the resulting time of getting from pasture 1 to N.
Input
* Line 1: Three space-separated integers: N, M, and K* Lines 2..M+1: Line i+1 describes trail i with three space-separated        integers: P1_i, P2_i, and T_i
Output
* Line 1: The length of the shortest path after revamping no more than        K edges
Sample Input
4 4 11 2 102 4 101 3 13 4 100
Sample Output
1注:这道题刚开始我用分层图的思想做,分为(k + 1)层,但是内存太大了,总是RE,没办法,只能用dijkstra+优先队列+动态规划做了,且状态转移是从底层图到高层图。source code:
#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;typedef long long ll;const int inf = 0x3fffffff;const int maxn = 10005;const int maxm = 100050;int head[maxn], next[maxm], vis[maxn];ll dis[maxn][25];int e, n, m, k;struct node{    int u, v;    int c;    node(){}    node(int u, int v, int c):u(u), v(v), c(c){}}p[maxm];void addnode(int u, int v, int c){    p[e] = node(u, v, c);    next[e] = head[u];    head[u] = e++;}struct ab{    int v, c;    ab(){}    ab(int v, int c) : v(v), c(c){}    bool operator < (const ab &other) const    {        return c > other.c;    }};bool relax(int u, int v, int c){    if (dis[v][0] > dis[u][0] + c) {        dis[v][0] = dis[u][0] + c;        return true;    }    return false;}void init(){    e = 0;    memset(head, -1, sizeof(head));    memset(next, -1, sizeof(next));}void dij(int s, int t){    for (int i = 1; i <= n; i++)        dis[i][0] = inf;    memset(vis, 0, sizeof(vis));    priority_queue<ab> que;    while (!que.empty())        que.pop();    dis[s][0] = 0;    que.push(ab(s, dis[s][0]));    while (!que.empty()) {        ab u = que.top();        que.pop();        if (vis[u.v])            continue;        vis[u.v] = 1;        for (int i = head[u.v]; i + 1; i = next[i]) {            if (relax(u.v, p[i].v, p[i].c) && !vis[p[i].v]) {                que.push(ab(p[i].v, dis[p[i].v][0]));            }        }    }}void dij2(int s, int t, int l){    for (int i = 1; i <= n; i++)        dis[i][l] = inf;    dis[s][l] = 0;    memset(vis, 0, sizeof(vis));    priority_queue<ab> que;    while (!que.empty())        que.pop();    que.push(ab(s, dis[s][l]));    while (!que.empty()) {        ab u = que.top();        que.pop();        if (vis[u.v])            continue;        vis[u.v] = 1;        for (int i = head[u.v]; i + 1; i = next[i]) {            if (dis[p[i].v][l] > min(dis[u.v][l] + p[i].c, dis[u.v][l - 1]) && !vis[p[i].v]) {                dis[p[i].v][l] = min(dis[u.v][l] + p[i].c, dis[u.v][l - 1]);                que.push(ab(p[i].v, dis[p[i].v][l]));            }        }    }}int main(){    freopen("F:\\test.txt", "r", stdin);    int u, v, w;    while (scanf("%d%d%d", &n, &m, &k) != EOF) {        init();        for (int i = 1; i <= m; i++) {            scanf("%d%d%d", &u, &v, &w);            addnode(u, v, w);            addnode(v, u, w);        }        dij(1, n);        for (int i = 1; i <= k; i++) {            dij2(1, n, i);        }        printf("%lld\n", dis[n][k]);    }    return 0;}



 
0 0