CDOJ 30 最短路

在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的T-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?

Input

输入包括多组数据。

每组数据第一行是两个整数N,M(N100,M10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。

接下来M行,每行包括3个整数A,B,C(1A,BN,1C1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。

输入保证至少存在1条商店到赛场的路线。

Output

对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间。

Sample input and output

Sample InputSample Output
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0
3
2
#include <iostream>
using namespace std;

const int inf=0x7fffffff;

struct adjvex{
    int num,w;
    adjvex *next;
};

struct node{
    int dis;
    bool flag;
    adjvex *next;
};

void build_G(node *v,adjvex *e,int n,int m) {
    int A,B,C,id=0;
    adjvex *p;
    for (int i=0; i<105; i++)
        v[i].next=NULL;
    for (int i=0; i<m; i++) {
        scanf("%d%d%d",&A,&B,&C);
        e[id].num=B;
        e[id].w=C;
        e[id].next=v[A].next;
        v[A].next=&e[id];
        id++;
        e[id].num=A;
        e[id].w=C;
        e[id].next=v[B].next;
        v[B].next=&e[id];
        id++;
    }
    for (int i=2; i<105; i++) {
        v[i].dis=inf;
        v[i].flag=0;
    }
    v[1].dis=0;
    v[1].flag=1;
    p=v[1].next;
    while (p!=NULL) {
        v[p->num].dis=p->w;
        p=p->next;
    }
}

void Dijkstra(node *v,int n) {
    int minw,minindex;
    adjvex *p;
    while (1) {
        minw=inf;
        minindex=-1;
        for (int j=2; j<=n; j++) {
            if (v[j].flag==0&&v[j].dis<minw) {
                minw=v[j].dis;
                minindex=j;
            }
        }
        if (minindex==-1) break;
        if (minindex==n) {
            printf("%d\n",v[n].dis);
            return;
        }
        v[minindex].flag=1;
        p=v[minindex].next;
        while (p!=NULL) {
            if (v[p->num].flag==0&&v[p->num].dis>v[minindex].dis+p->w)
                v[p->num].dis=v[minindex].dis+p->w;
            p=p->next;
        }
    }
    printf("%d\n",v[n].dis);
}

int main() {
    int N,M;
    while (scanf("%d%d",&N,&M)==2) {
        if (N==0&&M==0)
            break;
        node v[105];
        adjvex e[20010];
        build_G(v,e,N,M);
        Dijkstra(v,N);
    }
}

 如果要打印路径的话:

#include <iostream>
#include <stack>
using namespace std;

const int inf=0x7fffffff;
stack<int> trace;

struct adjvex{
    int num,w;
    adjvex *next;
};

struct node{
    int dis,last;
    bool flag;
    adjvex *next;
};

void build_G(node *v,adjvex *e,int n,int m) {
    int A,B,C,id=0;
    adjvex *p;
    for (int i=0; i<105; i++)
        v[i].next=NULL;
    for (int i=0; i<m; i++) {
        scanf("%d%d%d",&A,&B,&C);
        e[id].num=B;
        e[id].w=C;
        e[id].next=v[A].next;
        v[A].next=&e[id];
        id++;
        e[id].num=A;
        e[id].w=C;
        e[id].next=v[B].next;
        v[B].next=&e[id];
        id++;
    }
    for (int i=2; i<105; i++) {
        v[i].dis=inf;
        v[i].last=-1;
        v[i].flag=0;
    }
    v[1].dis=0;
    v[1].last=-1;
    v[1].flag=1;
    p=v[1].next;
    while (p!=NULL) {
        v[p->num].dis=p->w;
        v[p->num].last=1;
        p=p->next;
    }
}

void Dijkstra(node *v,int n) {
    int minw,minindex;
    adjvex *p;
    while (1) {
        minw=inf;
        minindex=-1;
        for (int j=2; j<=n; j++) {
            if (v[j].flag==0&&v[j].dis<minw) {
                minw=v[j].dis;
                minindex=j;
            }
        }
        if (minindex==-1) break;
        if (minindex==n) return;
        v[minindex].flag=1;
        p=v[minindex].next;
        while (p!=NULL) {
            if (v[p->num].flag==0&&v[p->num].dis>v[minindex].dis+p->w) {
                v[p->num].dis=v[minindex].dis+p->w;
                v[p->num].last=minindex;
            }
            p=p->next;
        }
    }
}

int main() {
    int N,M,t;
    while (scanf("%d%d",&N,&M)==2) {
        if (N==0&&M==0)
            break;
        node v[105];
        adjvex e[20010];
        build_G(v,e,N,M);
        Dijkstra(v,N);
        printf("%d:",v[N].dis);
        t=N;
        while (t!=1) {
            trace.push(t);
            t=v[t].last;
        }
        printf("1");
        while (!trace.empty()) {
            printf("->%d",trace.top());
            trace.pop();
        }
        printf("\n");
    }
}
posted @ 2017-12-02 19:34  soildom  阅读(197)  评论(0编辑  收藏  举报