hdu-2544-最短路(Dijkstra + Dijkstra优先队列 + Bellman-ford + SPFA +Floyd) 纯模板题

最短路

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)


Problem Description

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

Input

输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。

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

 
Output

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

 

Sample Input

2 1

1 2 3

3 3

1 2 5

2 3 5

3 1 2

0 0

 
Sample Output

3

2

 

题目链接:最短路

代码:

//Dijkstra
#include
#include
#include
#include

using namespace std;
const int MAX = 1 << 30;
int n,m,vis[110],dist[110];

struct node     //存储边的终点,以及权值
{
    int v,w;
    node(int vv,int ww) : v(vv),w(ww) {}
    node() {}
};

vector G[110];

void make_G()
{
    int st,ed,c;
    for(int i = 1;i <= n;i++) { //初始化
        G[i].clear();
        vis[i] = 0;
        dist[i] = MAX;
    }
    for(int i = 0;i < m;i++) {
        scanf("%d%d%d",&st,&ed,&c);
        G[st].push_back(node (ed,c));
        G[ed].push_back(node (st,c));
    }
}

void dijkstra()
{
    dist[1] = 0;
    for(int i = 0;i < n;i++) {  //从未选点集中选点,并加入已选点集
        int p,mn = MAX;
        for(int j = 1;j <= n;j++) { //未选点 中 距离 已选点 最近的点
            if(!vis[j] && dist[j] <= mn) {
                p = j,mn = dist[j];
            }
        }

        vis[p] = 1; //标记选择
        for(int j = 0;j < G[p].size();j++) {    //更新选择后的dist数组,也就是源点到其他点的最短距离
            if(dist[G[p][j].v ] > dist[p] + G[p][j].w){
                dist[G[p][j].v ] = dist[p] + G[p][j].w;
            }
        }
    }
    printf("%d\n",dist[n]);
}

int main()
{
    while(~scanf("%d%d",&n,&m) && n && m) {
        make_G();
        dijkstra();
    }
    return 0;
}#include
#include
#include
#include

using namespace std;
int n,m,vis[110];

struct node
{
    int v,w;
    node(int vv,int ww) : v(vv),w(ww) {}
    node() {}

    bool operator < (const node &a) const   //运算符重载,保证权值小的边优先级高
    {
        return w > a.w;
    }
};

vector G[110];

void make_G()
{
    int st,ed,c;
    for(int i = 1;i <= n;i++) { 
        G[i].clear();
        vis[i] = 0;
    }
    for(int i = 0;i < m;i++) { 
        scanf("%d%d%d",&st,&ed,&c);
        G[st].push_back(node (ed,c));
        G[ed].push_back(node (st,c));
    }
}

void dijkstra()
{
    priority_queue qe;
    qe.push(node (1,0));
    node p;
    while(!qe.empty()) {
        p = qe.top();
        qe.pop();
        if(vis[p.v]) continue;  //之前处理过(队列先处理最优的)
        vis[p.v] = 1;
        
        if(p.v == n) break;
        for(int i = 0;i < G[p.v].size();i++) {
            node q = G[p.v][i];
            if(!vis[q.v]) { //从已选点开始可更新的边都入队,当然也可以改成判断队列是否已经有这条边
                q.w = p.w + q.w;
                qe.push(node (q.v,q.w));
            }
        }
    }
    printf("%d\n",p.w);
}

int main()
{
    while(~scanf("%d%d",&n,&m) && n && m) {
        make_G();
        dijkstra();
    }
    return 0;
}//bellman-ford
#include
#include
#include
#include

using namespace std;
const int MAX = 1<<30;
int n,m,vis[110],dist[110];

struct node
{
    int u,v,w;
    node(int uu,int vv,int ww) : u(uu),v(vv),w(ww) {}
    node() {}
};

vector G;

void make_G()
{
    int st,ed,c;
    G.clear();
    for(int i = 1;i <= n;i++) {
        vis[i] = 0;
        dist[i] = MAX;
    }
    for(int i = 0;i < m;i++) {
        scanf("%d%d%d",&st,&ed,&c);
        G.push_back(node (st,ed,c));
        G.push_back(node (ed,st,c));
    }
}

void bellman_ford()
{
    dist[1] = 0;
    for(int j = 1;j < n;j++) { //n-1次松弛
        for(int i = 0;i < G.size();i++) { //对每条边进行处理
            int u,v;
            u = G[i].u,v = G[i].v;
            if(dist[v] > dist[u] + G[i].w) {
                dist[v] = dist[u] + G[i].w;
            }
        }

        for(int i = 0;i < G.size();i++) { //此题可以省略
            int u,v;
            u = G[i].u,v = G[i].v;
            if(dist[v] > dist[u] + G[i].w) {
                printf("有环!\n");
            }
        }

    }
}

int main()
{
    while(~scanf("%d%d",&n,&m) && n && m) {
        make_G();
        bellman_ford();
        printf("%d\n",dist[n]);
    }
    return 0;
}#include
#include
#include
#include

using namespace std;
const int MAX = 1e7;
int n,m,dist[110];

struct node
{
    int v,w;
    node(int vv,int ww) : v(vv),w(ww) {}
    node() {}

    bool operator < (const node &a) const
    {
        return w > a.w;
    }
};

vector G[110];

void make_G()
{
    int st,ed,c;
    for(int i = 1;i <= n;i++) {
        dist[i] = MAX;
        G[i].clear();
    }
    for(int i = 0;i < m;i++) {
        scanf("%d%d%d",&st,&ed,&c);
        G[st].push_back(node (ed,c));
        G[ed].push_back(node (st,c));
    }
}

void spfa()
{
    priority_queue qe;
    int updataTimes[110];
    memset(updataTimes,0,sizeof(updataTimes));

    node p = node (1,0);
    qe.push(p);
    dist[p.v] = 0;
    while(!qe.empty()) {
        p = qe.top();
        qe.pop();
        for(int i = 0;i < G[p.v].size();i++) {
            node q = G[p.v][i];
            if(dist[q.v] > dist[p.v] + q.w) {
                dist[q.v] = dist[p.v] + q.w;
                qe.push(node (q.v,dist[q.v]));
                if(++ updataTimes[q.v] >= n) {  //更新次数超过n次,有环
                    printf("有环\n");
                }
            }
        }
    }
    printf("%d\n",dist[n]);
}

int main()
{
    while(~scanf("%d%d",&n,&m) && n && m) {
        make_G();
        spfa();
    }
    return 0;
}#include
#include
#include
#include

using namespace std;
const int MAX = 1 << 30;
int n,m,path[110][110];

void make_G()
{
    int st,ed,c;
    for(int i = 1;i <= n;i++) {
        for(int j = 1;j <= n;j++) {
            path[i][j] = MAX;
        }
    }
    for(int i = 0;i < m;i++) {
        scanf("%d%d%d",&st,&ed,&c);
        path[st][ed] = path[ed][st] = c;
    }
}

void floyd()
{
    for(int k = 1;k <= n;k++) { //注意枚举点的循环的位置
        for(int i = 1;i <= n;i ++) {
            for(int j = 1;j <= n;j++) {
                if(path[i][k] == MAX || path[k][j] == MAX) continue;
                if(path[i][j] > path[i][k] + path[k][j]) {
                    path[i][j] = path[i][k] + path[k][j];
                }
            }
        }
    }
}

int main()
{
    while(~scanf("%d%d",&n,&m) && n && m) {
        make_G();
        floyd();
        printf("%d\n",path[1][n]);
    }
    return 0;
}

                                                                                                                                                                                    

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/sinat_34263473/article/details/52161805
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞