hdu3790 最短路径问题(Dijkstra)

原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=3790

另外写文章之前偷懒一下,发现一个很好的入门python教程!:http://woodpecker.org.cn/abyteofpython_cn/chinese/

题意:在最短路径的前提下,添加了一个最短路径中权值最小的要求。

使用dijkstra算法。

注意此图是无向图,输入时保存最优的路径和权值。

具体细节在代码中:

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;
#define INF 0x1f1f1f1f //防止不用fffffff防止溢出
#define min(a, b) a < b? a : b
struct Cost
{
    int l;
    int c;
};

struct Low
{
    int l;
    int c;
};

Cost cost[1001][1001];
Low low[1001];
bool flag[1001];
int s; //出发点

void Dijkstra(int n)
{
    int i, j, k;
    memset(flag, 0, sizeof(flag));
    memset(low, 0x1f, sizeof(low));
    flag[s] = 1;
    for(i = 1; i <= n; i++)
    {
        low[i].l = cost[s][i].l; //s到任意点的距离
        low[i].c = cost[s][i].c; //s到任意点的花费
    }
    low[s].l = 0;
    low[s].c = 0;

    for(i = 2; i < n; i ++)
    {
        int min = INF;
        int val = INF;
        for(j = 1; j <= n; j++)
        {
            if(flag[j] == 0 && low[j].l <= min)//到当前点距离
            {
                if(low[j].l == min)
                {
                    if(low[j].c < val)
                    {
                        val = low[j].c;
                        k = j;
                    }
                    else //在length和value都相等的前提下,添加任何一个点都是一样的
                        continue;
                }
                else
                {
                    min = low[j].l;
                    val = low[j].c;
                    k = j;
                }
            }
        }
        flag[k] = 1;
        for(j = 1; j <= n; j++)
        {
            if(flag[j] == 0 && cost[k][j].l + low[k].l <= low[j].l)//依据这个点修改最短路径
            {
                if(cost[k][j].l + low[k].l < low[j].l)
                {
                    low[j].l = low[k].l + cost[k][j].l;
                    low[j].c = low[k].c + cost[k][j].c;
                }
                else
                {
                    low[j].c = min(low[j].c, cost[k][j].c + low[k].c);
                }
            }
        }
    }
}
void ace()
{
    int i, t;//work point
    int m, n;
    int a, b, d, p;
    while(scanf("%d%d", &n, &m))
    {
        if(m == 0 && n == 0)
            break;
        memset(cost, INF, sizeof(cost));
        for(i = 0; i < m; i++)
        {
            scanf("%d%d%d%d", &a,&b,&d,&p);
            if(cost[a][b].l > d)
            {
                cost[a][b].l = cost[b][a].l = d;
                cost[a][b].c = cost[b][a].c = p;
            }
            else if(cost[a][b].l == d && cost[a][b].c < p)
            {
                cost[a][b].c = cost[b][a].c = p;
            }
            else
                continue;
        }
        scanf("%d%d", &s, &t);

        Dijkstra(n);

        printf("%d %d\n", low[t].l, low[t].c);

    }
}

int main()
{
    ace();
    return 0;
}
时间: 2024-10-15 18:37:00

hdu3790 最短路径问题(Dijkstra)的相关文章

HDU3790 最短路径问题 【Dijkstra】

最短路径问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 13336    Accepted Submission(s): 4072 Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的. Input

HDU 2544:最短路( 最短路径入门 &amp;&amp;Dijkstra &amp;&amp; floyd )

最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 30972    Accepted Submission(s): 13345 Problem Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找

最短路径算法-Dijkstra算法的应用之单词转换(词梯问题)

一,问题描述 在英文单词表中,有一些单词非常相似,它们可以通过只变换一个字符而得到另一个单词.比如:hive-->five:wine-->line:line-->nine:nine-->mine..... 那么,就存在这样一个问题:给定一个单词作为起始单词(相当于图的源点),给定另一个单词作为终点,求从起点单词经过的最少变换(每次变换只会变换一个字符),变成终点单词. 这个问题,其实就是最短路径问题. 由于最短路径问题中,求解源点到终点的最短路径与求解源点到图中所有顶点的最短路径复

最短路径之Dijkstra算法

Dijkstra算法: 首先,引进一个辅助向量D,它的每个分量D[i]表示当前所找到的从始点v到每个终点vi的的长度:如D[3]=2表示从始点v到终点3的路径相对最小长度为2.这里强调相对就是说在算法过程中D的值是在不断逼近最终结果但在过程中不一定就等于长度.它的初始状态为:若从v到vi有弧,则D为弧上的权值:否则置D为∞.显然,长度为 D[j]=Min{D | vi∈V} 的路径就是从v出发的长度最短的一条.此路径为(v,vj). 那么,下一条长度次短的是哪一条呢?假设该次短路径的终点是vk,

最短路径问题-Dijkstra

概述 与前面说的Floyd算法相比,Dijkstra算法只能求得图中特定顶点到其余所有顶点的最短路径长度,即单源最短路径问题. 算法思路 1.初始化,集合K中加入顶点v,顶点v到其自身的最短距离为0,到其它所有顶点为无穷. 2.遍历与集合K中结点直接相邻的边(U,V,C),其中U属于集合K,V不属于集合K,计算由结点v出发,按照已经得到的最短路径到达U,再由U经过该边达到V时的路径长度.比较所有与集合K中结点直接相邻的非集合K结点该路径长度,其中路径长度最小的顶点被确定为下一个最短路径确定的结点

单源最短路径算法---Dijkstra

Dijkstra算法树解决有向图G=(V,E)上带权的单源最短路径问题,但是要求所有边的权值非负. 解题思路: V表示有向图的所有顶点集合,S表示那么一些顶点结合,从源点s到该集合中的顶点的最终最短路径的权值(程序中用dist[i]表示)已经确定.算法反复选择具有最短路径估计的顶点u 属于 V-S(即未确定最短路径的点,程序中finish[i]=false的点),并将u加入到S中(用finish[i]=true表示),最后对u的所有输出边进行松弛. 程序实现:      输入数据: 5 7 0

有向有权图的最短路径算法--Dijkstra算法

Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很有代表性的最短路径算法, 在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等.注意该算法要求图中不存在负权边. 问题描述:在无向图 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径.(单源最短路径) 2.算

hdu3790最短路径问题

这是一个最短路径的裸题,我们在边结构体中 添加成员路径和花费,然后在松弛操作的时候用这两个来松弛就OK // AC 840k 109ms #include<cstdio> #include<queue> using namespace std; #define MAX 1001 #define IFN 1<<30-1 struct node { int to,len,cost,next; }edge[MAX*100*2]; int head[MAX],tol; int

图的单源最短路径:Dijkstra算法实现

本文介绍的是图的非负权值的单源最短路径问题.问题的提出是,对于有权图D,t提供源点v,要找到从v到其他所有点的最短路径,即单源最短路径问题,在本文中,解决这一问题,是普遍比较熟悉的Dijkstra算法. 算法核心思想参见维基.简而言之,设集合S存放已经求出了最短路径的点.初始状态S中只有一个点v0,之后每求得v0到vn的最短路径,就会更新v0到所有vn邻接的点的一致的最短路径(不一定是最终的最短路径),如此重复,每次会确定v0到一个点的最短路径,确定好的点加入S中,直至所有点进入S结束.在本文中

单源最短路径(dijkstra算法)php实现

做一个医学项目,其中在病例评分时会用到单源最短路径的算法.单源最短路径的dijkstra算法的思路如下: 如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点.那么(Vi...Vk)也必定是从i到k的最短路径.Dijkstra是以最短路径长度递增,逐次生成最短路径的算法.例如:对于源顶点V0,首先选择其直接相邻的顶点中长度最短的顶点Vi,那么当前已知可得从V0到达Vj顶点的最短距离dist[j]=min{dist[j],dist[i]+cost[i][j]}.假设G