PAT 1030. Travel Plan

来源:互联网 发布:网络词毛线是什么意思 编辑:程序博客网 时间:2024/05/22 17:28

这个题做了一个下午,刚开始用Java写,

<span style="font-size:14px;">import java.util.*;public class Main {static int INF = 99999999;public static void main(String[] args) {Scanner sc = new Scanner(System.in);int N = sc.nextInt();int M = sc.nextInt();int start = sc.nextInt();int end   = sc.nextInt();int[][] d = new int[N][N];int[][] c = new int[N][N];for(int i=0; i<N; i++)for(int j=0; j<N; j++) {d[i][j] = INF;c[i][j] = INF;}for(int i=0; i<M; i++) {int c1 = sc.nextInt();int c2 = sc.nextInt();int d1  = sc.nextInt();int cc = sc.nextInt();d[c1][c2] = d1;d[c2][c1] = d1;c[c1][c2] = cc;c[c2][c1] = cc;}boolean[] marked = new boolean[N];int[] dist = new int[N];for(int i=0; i<N; i++)dist[i] = d[start][i];int[] cost = new int[N];for(int i=0; i<N; i++)cost[i] = c[start][i];int[] prev = new int[N];marked[start] = true;dist[start] = 0;cost[start] = 0;int newP = start;while(newP != end) {for(int i=0; i<N; i++) {if(!marked[i] && d[newP][i] < INF) {if(dist[newP] + d[newP][i] < dist[i]) {dist[i] = dist[newP] + d[newP][i];cost[i] = cost[newP] + c[newP][i];prev[i] = newP;} else if(dist[newP] + d[newP][i] == dist[i]) {if(cost[newP] + c[newP][i] < cost[i]) {cost[i] = cost[newP] + c[newP][i];prev[i] = newP; }}}}int min = INF;for(int i=0; i<N; i++) {if(!marked[i] && dist[i] < min) {min = dist[i];newP = i;}}marked[newP] = true;}StringBuilder sb = new StringBuilder();int t = end;while(t != start) {sb.insert(0, t + " ");t = prev[t];}sb.insert(0, start + " ");sb.append(dist[end]);sb.append(" " + cost[end]); System.out.println(sb);}}</span><span style="font-size:24px;"></span>

提示内存超了,改用C++写,还是超了,然后参考了别人的博客,PAT 1030. Travel Plan (30) (最短路),算法思路都差不多,但是它可以AC,好吧,那我就一点一点的改成你的样子,然而几个小时之后终于在它的输出上看出来了问题所在。。。。

输出我写的循环条件是
<span style="font-size: 14px;">while(t != start)</span>

而实际上在Dijkstra初始化时

<span style="font-size: 14px;"><span style="font-size:24px;">marked[start] = true;</span></span>
所以在第一次循环的时候下面的语句是不会被执行的

<span style="font-size: 14px;"><span style="font-size:24px;"><span style="font-size:24px;">prev[i] = newP;</span></span></span>

所以造成的结果是一直在死循环,一直往StringBuilder中append数据,所以最终要么超时,要么内存超限。但是也不能用默认赋值的0,因为节点就是从0开始的,可能会导致提前退出循环。

修改了之后,终于AC。。。。

<span style="font-size:14px;">package p1030;import java.util.*;public class Main {static int INF = 99999999;public static void main(String[] args) {Scanner sc = new Scanner(System.in);int N = sc.nextInt();int M = sc.nextInt();int start = sc.nextInt();int end   = sc.nextInt();int[] prev = new int[N];int[][] d = new int[N][N];int[][] c = new int[N][N];for(int i=0; i<N; i++) {prev[i] = -1;for(int j=0; j<N; j++) {d[i][j] = INF;c[i][j] = INF;}}for(int i=0; i<M; i++) {int c1 = sc.nextInt();int c2 = sc.nextInt();int d1  = sc.nextInt();int cc = sc.nextInt();d[c1][c2] = d1;d[c2][c1] = d1;c[c1][c2] = cc;c[c2][c1] = cc;}boolean[] marked = new boolean[N];int[] dist = new int[N];for(int i=0; i<N; i++)dist[i] = d[start][i];int[] cost = new int[N];for(int i=0; i<N; i++)cost[i] = c[start][i];marked[start] = true;dist[start] = 0;cost[start] = 0;int newP = start;while(newP != end) {for(int i=0; i<N; i++) {if(!marked[i] && d[newP][i] < INF) {if(dist[newP] + d[newP][i] < dist[i]) {dist[i] = dist[newP] + d[newP][i];cost[i] = cost[newP] + c[newP][i];prev[i] = newP;} else if(dist[newP] + d[newP][i] == dist[i]) {if(cost[newP] + c[newP][i] < cost[i]) {cost[i] = cost[newP] + c[newP][i];prev[i] = newP; }}}}int min = INF;for(int i=0; i<N; i++) {if(!marked[i] && dist[i] < min) {min = dist[i];newP = i;}}marked[newP] = true;}StringBuilder sb = new StringBuilder();int t = end;while(t != -1) {sb.insert(0, t + " ");t = prev[t];}sb.insert(0, start + " ");sb.append(dist[end]);sb.append(" " + cost[end]); System.out.println(sb);}}</span>


另外在附上C++代码

#include <cstdio>#include <cstdlib>#include <vector>#include <stack>using namespace std;const int MAX = 501;const int INF = 999999999;int N, M, start, t, c1, c2, d1, cc, i, j;int d[MAX][MAX], c[MAX][MAX];int marked[MAX];int dist[MAX], cost[MAX], pre[MAX];vector<int> v;stack<int> path;int main(){    //for(int i=0; i<MAX; i++)        //printf("%d ", &marked[i]);    scanf("%d %d %d %d", &N, &M, &start, &t);    for(i=0; i<N; i++) {        //marked[i] = 0;        pre[i] = -1;        for(j=0; j<N; j++) {            d[i][j] = INF;            c[i][j] = INF;        }    }    for(i=0; i<M; i++) {        scanf("%d %d %d %d", &c1, &c2, &d1, &cc);        d[c1][c2] = d1;        d[c2][c1] = d1;        c[c1][c2] = cc;        c[c2][c1] = cc;    }    for(i=0; i<N; i++) {        dist[i] = d[start][i];        cost[i] = c[start][i];    }    marked[start] = 1;    dist[start] = 0;    cost[start] = 0;    int newP = start;    while(newP != t) {        for(i=0; i<N; i++) {            if(marked[i] == 0 && d[newP][i] < INF) {                if(dist[newP] + d[newP][i] < dist[i]) {                    dist[i] = dist[newP] + d[newP][i];                    cost[i] = cost[newP] + c[newP][i];                    pre[i] = newP;                } else if(dist[newP] + d[newP][i] == dist[i]) {                    if(cost[newP] + c[newP][i] < cost[i]) {                        cost[i] = cost[newP] + c[newP][i];                        pre[i] = newP;                    }                }            }        }        int min_dist = INF;        for(i=0; i<N; i++) {            if(marked[i] == 0 && dist[i] < min_dist) {                min_dist = dist[i];                newP = i;            }        }        marked[newP] = 1;    }    int p = pre[t];    while(p!=-1){        path.push(p);        p = pre[p];    }    printf("%d",start);    while(!path.empty()){        printf(" %d",path.top());        path.pop();    }    printf(" %d",t);    printf(" %d %d\n",dist[t],cost[t]);}




1 0
原创粉丝点击