数据结构第13周 :( 迪杰斯特拉最短路径 + 弗洛伊德求最短路径 + 欧拉回路 + Invitation Cards)

这篇具有很好参考价值的文章主要介绍了数据结构第13周 :( 迪杰斯特拉最短路径 + 弗洛伊德求最短路径 + 欧拉回路 + Invitation Cards)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

迪杰斯特拉最短路径

【问题描述】

在带权有向图G中,给定一个源点v,求从v到G中的其余各顶点的最短路径问题,叫做单源点的最短路径问题。

在常用的单源点最短路径算法中,迪杰斯特拉算法是最为常用的一种,是一种按照路径长度递增的次序产生最短路径的算法。
在本题中,读入一个有向图的带权邻接矩阵(即数组表示),建立有向图并按照以上描述中的算法求出源点至每一个其它顶点的最短路径长度。

【输入形式】

输入的第一行包含2个正整数n和s,表示图中共有n个顶点,且源点为s。其中n不超过50,s小于n。

以后的n行中每行有n个用空格隔开的整数。对于第i行的第j个整数,如果大于0,则表示第i个顶点有指向第j个顶点的有向边,且权值为对应的整数值;如果这个整数为0,则表示没有i指向j的有向边。当i和j相等的时候,保证对应的整数为0。

【输出形式】

只有一行,共有n-1个整数,表示源点至其它每一个顶点的最短路径长度。如果不存在从源点至相应顶点的路径,输出-1。

请注意行尾输出换行。

【样例输入】

4 1
0 3 0 1
0 0 4 0
2 0 0 0
0 0 1 0

【样例输出】

6 4 7

【样例说明】

在本题中,需要按照题目描述中的算法完成迪杰斯特拉算法,并在计算最短路径的过程中将每个顶点是否可达记录下来,直到求出每个可达顶点的最短路径之后,算法才能够结束。

迪杰斯特拉算法的特点是按照路径长度递增的顺序,依次添加下一条长度最短的边,从而不断构造出相应顶点的最短路径。

另外需要注意的是,在本题中为了更方便的表示顶点间的不可达状态,可以使用一个十分大的值作为标记。

#include<iostream>
#define N 50
#define Max 99999
using namespace std;

int NodeNum;
int SourceNum;
int R[N][N];
int dist[N];
int path[N];
bool tag[N];

void Dijkstra()
{
    int i = 0;
    for(i = 0; i < NodeNum; i ++)
    {
        dist[i] = R[SourceNum][i];
        if(i == SourceNum)
        {
            path[i] = -1;
            tag[i] = false;
        }
        else
        {
            path[i] = SourceNum;
            tag[i] = true;
        }
    }

    int cnt = NodeNum - 1;
    while(cnt --)
    {
        int Min = Max;
        int MinId = 0;
        for(i = 0; i < NodeNum; i ++) //找到未访问的最小邻接顶点,并入,将tag置为零
        {
            if(dist[i] < Min && tag[i] == true)
            {
                Min = dist[i];
                MinId = i;
            }
        }
        tag[MinId] = false;
        for(i = 0; i < NodeNum; i ++)
        {
            if(i == MinId || i == SourceNum) continue;
            if(R[MinId][i] + dist[MinId] < dist[i])
            {
                dist[i] = R[MinId][i] + dist[MinId];
                path[i] = MinId;
            }
        }
    }
    for(i = 0; i < NodeNum; i ++)
    {
        if(i == SourceNum) continue;
        if(dist[i] == Max) cout<<-1<<" ";
        else
            cout<<dist[i]<<" ";
    }
}

int main()
{
    cin>>NodeNum>>SourceNum;
    int i, j;
    for(i = 0; i < NodeNum; i ++)
    {
        for(j = 0; j < NodeNum; j ++)
        {
            int num;
            cin>>num;
            if(num == 0)
                R[i][j] = Max;
            else
                R[i][j] = num;
        }
    }
    Dijkstra();
    return 0;
}

弗洛伊德求最短路径

【问题描述】

对于下面一张若干个城市,以及城市之间距离的地图,请采用弗洛伊德算法求出所有城市之间的最短路径。
【输入形式】

顶点个数n,以及n*n的邻接矩阵,其中不可达使用9999代替

【输出形式】

每两个顶点之间的最短路径和经过的顶点

注意:顶点自身到自身的dist值为0,path则为该顶点的编号

【样例输入】

4

9999 4 11 9999

6 9999 2 9999

1 9999 9999 1

9999 3 9999 9999

【样例输出】

from 0 to 0: dist = 0 path:0
from 0 to 1: dist = 4 path:0 1
from 0 to 2: dist = 6 path:0 1 2
from 0 to 3: dist = 7 path:0 1 2 3
from 1 to 0: dist = 3 path:1 2 0
from 1 to 1: dist = 0 path:1
from 1 to 2: dist = 2 path:1 2
from 1 to 3: dist = 3 path:1 2 3
from 2 to 0: dist = 1 path:2 0
from 2 to 1: dist = 4 path:2 3 1
from 2 to 2: dist = 0 path:2
from 2 to 3: dist = 1 path:2 3
from 3 to 0: dist = 6 path:3 1 2 0
from 3 to 1: dist = 3 path:3 1
from 3 to 2: dist = 5 path:3 1 2
from 3 to 3: dist = 0 path:3

#include<iostream>
#define N 50
using namespace std;

int dist[N][N];
int path[N][N];
int NodeNum;
void Floyd()
{
    int i, j, k;
    for(k = 0; k < NodeNum; k ++)
    {
        for(i = 0; i < NodeNum; i ++)
        {
            for(j = 0; j < NodeNum; j ++)
            {
                if(i == j || k == i || k == j) continue;
                if(dist[i][j] > dist[i][k] + dist[k][j])
                {
                    dist[i][j] = dist[i][k] + dist[k][j];
                    path[i][j] = path[i][k];
                }
            }
        }
    }
    for(i = 0; i < NodeNum; i ++)
    {
        for(j = 0; j < NodeNum; j ++)
        {
            cout<<"from "<<i<<" to "<<j<<": dist = ";
            if(dist[i][j] == 9999)
                cout<<0;
            else
                cout<<dist[i][j];
            cout<<" path:";
            int t = path[i][j];
            cout<<i<<" ";
            if(t == j )
            {
                if(i != j)
                    cout<<j;
            }
            else
            {
                cout<<path[i][j]<<" ";
                while(t != j)
                {
                    cout<<path[t][j]<<" ";
                    t = path[t][j];
                }
            }

            cout<<endl;
        }
    }
}

int main()
{
    cin>>NodeNum;
    int i, j;
    for(i = 0; i <NodeNum; i ++)
    {
        for(j = 0; j <NodeNum; j ++)
        {
            cin>>dist[i][j];
            path[i][j] = j;
        }
    }
    Floyd();
    return 0;
}

欧拉回路

【问题描述】

欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?

【输入形式】

测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。当N为0时输入结束。

【输出形式】

每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。

【样例输入】

3 3

1 2

1 3

2 3

3 2

1 2

2 3

0

【样例输出】

1

0

【备注】

此题是浙大计算机研究生复试上机考试-2008年真题。

#include<iostream>
using namespace std;
int main()
{
    while(1)
    {
        int NodeNum;
        int RelationNum;
        cin>>NodeNum;
        if(NodeNum == 0) break;
        cin>>RelationNum;
        int In[NodeNum];
        while(RelationNum --)
        {
            int n1;
            int n2;
            cin>>n1>>n2;
            In[n1 - 1] ++;
            In[n2 - 1] ++;
        }
        int flag = 1;
        int i = 0;
        for(i = 0; i < NodeNum; i ++)
        {
            if(In[i] % 2 != 0) flag = 0;
        }
        if(flag) cout<<1<<endl;
        else cout<<0<<endl;
    }
    return 0;
}

Invitation Cards

【Problem Description】

In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They want to propagate theater and, most of all, Antique Comedies. They have printed invitation cards with all the necessary information and with the programme. A lot of students were hired to distribute these invitations among the people. Each student volunteer has assigned exactly one bus stop and he or she stays there the whole day and gives invitation to people travelling by bus. A special course was taken where students learned how to influence people and what is the difference between influencing and robbery.

The transport system is very special: all lines are unidirectional and connect exactly two stops. Buses leave the originating stop with passangers each half an hour. After reaching the destination stop they return empty to the originating stop, where they wait until the next full half an hour, e.g. X:00 or X:30, where ‘X’ denotes the hour. The fee for transport between two stops is given by special tables and is payable on the spot. The lines are planned in such a way, that each round trip (i.e. a journey starting and finishing at the same stop) passes through a Central Checkpoint Stop (CCS) where each passenger has to pass a thorough check including body scan.

All the ACM student members leave the CCS each morning. Each volunteer is to move to one predetermined stop to invite passengers. There are as many volunteers as stops. At the end of the day, all students travel back to CCS. You are to write a computer program that helps ACM to minimize the amount of money to pay every day for the transport of their employees.

【Input】

The input consists of N cases. The first line of the input contains only positive integer N. Then follow the cases. Each case begins with a line containing exactly two integers P and Q, 1 <= P,Q <= 1000000. P is the number of stops including CCS and Q the number of bus lines. Then there are Q lines, each describing one bus line. Each of the lines contains exactly three numbers - the originating stop, the destination stop and the price. The CCS is designated by number 1. Prices are positive integers the sum of which is smaller than 1000000000. You can also assume it is always possible to get from any stop to any other stop.

【Output】

For each case, print one line containing the minimum amount of money to be paid each day by ACM for the travel costs of its volunteers.

【Sample Input】

2

2 2

1 2 13

2 1 33

4 6

1 2 10

2 1 60

1 3 20

3 4 10

2 4 5

4 1 50

【Sample Output】

46

210文章来源地址https://www.toymoban.com/news/detail-534318.html

#include<iostream>
#define N 50
#define Max 99999
using namespace std;

int dist[N][N];

void MinCost(int limit) //limit可取
{
    int i, j, k; //通过弗洛伊德的三重循环计算出每两个顶点间的最短距离
    for(k = 1; k <= limit; k ++)
    {
        for(i = 1; i <= limit; i ++)
        {
            for(j = 1; j <= limit; j ++)
            {
                if(i == j || k == i || k == j)continue;
                if(dist[i][k] + dist[k][j] < dist[i][j])
                {
                    dist[i][j] = dist[i][k] + dist[k][j];
                }
            }
        }
    }
    int res = 0;
    for(j = 2; j <= limit; j ++)
    {
        res += dist[1][j];
        res += dist[j][1];
    }
    cout<<res<<endl;
}

int main()
{
    int cnt = 0;
    cin>>cnt;
    while(cnt --)
    {
        int NodeNum;
        int RelationNum;
        cin>>NodeNum>>RelationNum;
        int i, j;
        for(i = 0; i < N; i ++)
        {
            for(j = 0; j < N; j ++)
            {
                dist[i][j] = Max;
            }
        }
        while(RelationNum --)
        {
            int n1;
            int n2;
            int w;
            cin>>n1>>n2>>w;
            dist[n1][n2] = w; //从下标一号开始
        }
        MinCost(NodeNum);
    }
    return 0;
}

到了这里,关于数据结构第13周 :( 迪杰斯特拉最短路径 + 弗洛伊德求最短路径 + 欧拉回路 + Invitation Cards)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构 -最短路径dijkstra(迪杰斯特拉)算法讲解及代码实现

            迪杰斯特拉算法是一种广义的贪心算法,求出局部最优解,再去求全局最优解 举例图:(起始点为1) 辅助数组: s:记录了目标顶点到其他顶点的最短路径是否求得(求得为1,否则为0) p:目标顶点到其他顶点的最短路径的前驱节点 (如,求得1-7-5的最短路径,那

    2024年02月11日
    浏览(25)
  • 数据结构与算法 —— 最短路径Dijkstra算法(迪杰斯特拉)详细图解以及python实现

    目录 前言 1. 介绍 2. 加权图 2.1 概念 3. 最短路径 -- Dijkstra 算法 3.1 历史 3.2 Dijkstra 算法的基本思路 3.3 Dijkstra 算法图解 4.  python中dijkstra算法的实现 5. 总结  前两章我们讲到了关于图的基本知识,和广度/深度优先搜索。 本章,我们将介绍 加权图 和 最短路径 的相关知识。 最

    2024年02月12日
    浏览(41)
  • 【数据结构】最小生成树(Prim算法,普里姆算法,普利姆)、最短路径(Dijkstra算法,迪杰斯特拉算法,单源最短路径)

    问题解答 (1)最小生成树(Minimal Spanning Tree)的定义 生成树的代价 :设 G ( V , E ) G(V,E) G ( V , E ) 是一个无向连通网图,生成树上 各边的权值之和 称为 生成树的代价 。 最小生成树 :在图 G G G 所有生成树中, 代价最小的生成树 为 最小生成树 。 (2)最小生成树(MST)的性

    2024年02月11日
    浏览(31)
  • 数据结构学习记录——图-最短路径问题(无权图单源最短路径算法、有权图单源最短路径算法、多源最短路径算法、Dijkstra(迪杰斯特拉)算法、Floyd算法)

    目录 问题分类  无权图单源最短路径算法 思路 伪代码 时间复杂度 代码实现(C语言) 有权图单源最短路径算法 Dijkstra(迪杰斯特拉)算法 伪代码  时间复杂度  代码实现(C语言) 多源最短路径算法 两种方法 Floyd算法 代码实现(C语言) 最短路径问题的抽象 在网络中,求

    2024年02月08日
    浏览(49)
  • 【数据结构与算法】迪杰斯特拉算法

    介绍 迪杰斯特拉(Dijkstra)算法是 典型最短路径算法 ,用于计算一个节点到其他节点的最短路径。它的主要特点是以中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。 算法过程 设置出发顶点为 v,顶点集合 V{v1,v2,v3…vi},v 到 V 中各顶点的距离构成距离集合

    2024年02月11日
    浏览(34)
  • 数据结构--迪杰斯特拉(Dijkstra)算法

    生活封锁了我们,只要我们的心不死,生活便永远不是一汪死水,而我们,依然会绽放最美的姿态。 戴克斯特拉算法(英语:Dijkstra’s algorithm),又称迪杰斯特拉算法、Dijkstra算法,是由荷兰计算机科学家艾兹赫尔·戴克斯特拉在1956年发现的算法,并于3年后在期刊上发表。

    2024年02月04日
    浏览(37)
  • 最短路径:迪杰斯特拉算法

    简介         英文名Dijkstra         作用:找到路中指定起点到指定终点的带权最短路径 核心步骤         1)确定起点,终点         2)从未走过的点中选取从起点到权值最小点作为中心点         3)如果满足 起点到中心点权值 + 中心点到指定其他点的

    2024年02月08日
    浏览(30)
  • 最短路径——迪杰斯特拉算法

    日常生活中常常涉及最短路径问题,如在一个城市交通网中,如何选取从起点到达终点的路径,才能使这一趟旅程的路程最短?或所需时间最少?或所需交通费用最低?诸如此类问题都可以抽象为 求解图的最短路径问题 。我们把 图的顶点 表示为 城市的交通站点 , 边表示交

    2024年02月04日
    浏览(35)
  • 迪杰斯特拉算法(求最短路径)

    迪杰斯特拉算法用于查找图中某个顶点到其它所有顶点的最短路径,该算法既适用于无向加权图,也适用于有向加权图。 注意,使用迪杰斯特拉算法查找最短路径时,必须保证图中所有边的权值为非负数,否则查找过程很容易出错。 迪杰斯特拉算法的实现思路 图 1 是一个无

    2024年02月02日
    浏览(29)
  • 迪杰斯特拉算法 – 图的单源最短路径

    迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。迪杰斯特拉算法采

    2024年02月05日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包