POJ2457 dijksta求最短路&&输出走过的路径

来源:互联网 发布:数据库设计范式 编辑:程序博客网 时间:2024/05/22 05:24

http://poj.org/problem?id=2457

题意:求起点1到终点m的最短距离。这个可以spfa||dijkstra。这题关键的是要输出从1--m走过的路径。用path[]记录下,每一步的祖先,用shortest[]逆序输出即可。这题re了n次。到现在也不理解,为什么先

if(dis[m]==INF){//为什么先判断就不会re.不明白
printf("-1\n");
continue;
}

这个就没问题。

View Code
// I'm lanjiangzhou//C#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <math.h>#include <time.h>//C++#include <iostream>#include <algorithm>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <cctype>#include <stack>#include <string>#include <list>#include <queue>#include <map>#include <vector>#include <deque>#include <set>using namespace std;//*************************OUTPUT*************************#ifdef WIN32#define INT64 "%I64d"#define UINT64 "%I64u"#else#define INT64 "%lld"#define UINT64 "%llu"#endif//**************************CONSTANT***********************#define INF 0x3f3f3f3f#define eps 1e-8#define PI acos(-1.)#define PI2 asin (1.);typedef long long LL;//typedef __int64 LL;   //codeforcestypedef unsigned int ui;typedef unsigned long long ui64;#define MP make_pairtypedef vector<int> VI;typedef pair<int, int> PII;#define pb push_back#define mp make_pair//***************************SENTENCE************************#define CL(a,b) memset (a, b, sizeof (a))#define sqr(a,b) sqrt ((double)(a)*(a) + (double)(b)*(b))#define sqr3(a,b,c) sqrt((double)(a)*(a) + (double)(b)*(b) + (double)(c)*(c))//****************************FUNCTION************************template <typename T> double DIS(T va, T vb) { return sqr(va.x - vb.x, va.y - vb.y); }template <class T> inline T INTEGER_LEN(T v) { int len = 1; while (v /= 10) ++len; return len; }template <typename T> inline T square(T va, T vb) { return va * va + vb * vb; }// aply for the memory of the stack//#pragma comment (linker, "/STACK:1024000000,1024000000")//end#define maxn 2100int n,m;int edges[maxn][maxn];int S[maxn];int dis[maxn];int path[maxn];int shortest[maxn];void dijkstra(int v0){    for(int i=1;i<=m;i++){        dis[i]=edges[v0][i];        S[i]=0;        if(i!=v0&&dis[i]<INF) path[i]=v0;        else path[i]=-1;    }    S[v0]=1;  dis[v0]=0;    for(int i=1;i<=m-1;i++){        int min=INF,u=v0;        for(int j=1;j<=m;j++){            if(!S[j]&&dis[j]<min){                u=j;                min=dis[j];            }        }        S[u]=1;        for(int k=1;k<=m;k++){            if(!S[k]&&edges[u][k]<INF&&dis[u]+edges[u][k]<dis[k]){                dis[k]=dis[u]+edges[u][k];                path[k]=u;            }        }    }}int main(){    while(scanf("%d%d",&n,&m)!=EOF){        int u,v;        //³õʼ»¯        for(int i=1;i<=m;i++){            for(int j=1;j<=m;j++){                edges[i][j]=INF;            }            edges[i][i]=0;        }        for(int i=1;i<=n;i++){            scanf("%d%d",&u,&v);            edges[u][v]=1;        }        dijkstra(1);        if(dis[m]==INF){//为什么先判断就不会re.不明白            printf("-1\n");            continue;        }        //printf("dis[m]=%d\n",dis[m]);        memset(shortest,0,sizeof(shortest));        int k=0;        shortest[k]=m;        while(path[shortest[k]]!=1){            k++;  shortest[k]=path[shortest[k-1]];        }        k++;  shortest[k]=1;//        if(dis[m]==INF){//为什么把dis[m]==INF放在这里就不会re.擦,re了13次。//            printf("-1\n");//        }       // else {            printf("%d\n",dis[m]+1);            for(int j=k;j>0;j--){                printf("%d\n",shortest[j]);            }            printf("%d\n",shortest[0]);        //}    }    return 0;}