SDUT-3363_驴友计划

数据结构实验之图论七:驴友计划

Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description

做为一个资深驴友,小新有一张珍藏的自驾游线路图,图上详细的标注了全国各个城市之间的高速公路距离和公路收费情况,现在请你编写一个程序,找出一条出发地到目的地之间的最短路径,如果有多条路径最短,则输出过路费最少的一条路径。

Input

连续T组数据输入,每组输入数据的第一行给出四个正整数N,M,s,d,其中N(2 <= N <= 500)是城市数目,城市编号从0~N-1,M是城市间高速公路的条数,s是出发地的城市编号,d是目的地的城市编号;随后M行,每行给出一条高速公路的信息,表示城市1、城市2、高速公路长度、收费额,中间以空格间隔,数字均为整数且不超过500,输入数据均保证有解。

Output

在同一行中输出路径长度和收费总额,数据间用空格间隔。

Sample Input

1
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20

Sample Output

3 40

题解:求最短路问题,可以用迪杰斯特拉算法求解。

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int S,E;/*起点终点*/
int n;/*n节点数量*/
int f[1050];/*记录点是否被遍历过*/
int INF = 1e9+7;/*相当于无穷大*/

struct node
{
    int w,l;
}s[505][505],dis[505];/*利用邻接矩阵来记录图*/

void dij()
{
    int k,i,j,f[505];
    struct node MIN;
    for(i=0;i<n;i++)
    {
        dis[i] = s[S][i];
        f[i] = 0;
    }
    f[S] = 1;
    for(i=1;i<n;i++)
    {
        MIN.l = MIN.w = INF;
        k = -1;
        for(j=0;j<n;j++)
        {
            if(!f[j])
            {
                if(dis[j].l<MIN.l)
                {
                    MIN = dis[j];
                    k = j;
                }
                else if(dis[j].l==MIN.l&&dis[j].w<MIN.w)
                {
                    MIN = dis[j];
                    k = j;
                }
            }
        }
        if(k==-1)
            break;
        f[k] = 1;
        for(j=0;j<n;j++)
        {
            if(!f[j])
            {
                if(dis[j].l>dis[k].l+s[k][j].l)
                {
                    dis[j].l = dis[k].l + s[k][j].l;
                    dis[j].w = dis[k].w + s[k][j].w;
                }
                else if(dis[j].l == dis[k].l+s[k][j].l&&dis[j].w>dis[k].w+s[k][j].w)
                {
                    dis[j].l = dis[k].l + s[k][j].l;
                    dis[j].w = dis[k].w + s[k][j].w;
                }
            }
        }
    }
    printf("%d %d\n",dis[E].l,dis[E].w);
}

int main()
{
    int m,i,j,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d%d",&n,&m,&S,&E);
        for(i=0;i<n;i++)
            for(j=0;j<n;j++)
                s[i][j].w = s[i][j].l = i==j?0:INF;
        for(i=0;i<m;i++)
        {
            int a,b,c,d;
            scanf("%d%d%d%d",&a,&b,&c,&d);
            if(s[a][b].l>c)
            {
                s[a][b].l = s[b][a].l = c;
                s[a][b].w = s[b][a].w = d;
            }
            else if(s[a][b].l==c&&s[a][b].w>d)
            {
                s[a][b].l = s[b][a].l = c;
                s[a][b].w = s[b][a].w = d;
            }
        }
        dij();
    }
    return 0;
}

posted @   洛沐辰  阅读(244)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示