【C++】「一本通 3.4.2 练习 3」最短路径(shopth)

【来源】

一本通-1378

【题目描述】

给出一个有向图 G = ( V , E ) G=(V, E) ,和一个源点 v 0 V v_0∈V ,请写一个程序输出 v 0 v_0 和图 G G 中其它顶点的最短路径。只要所有的有向环权值和都是正的,我们就允许图的边有负值。顶点的标号从 1 1 n n n n 为图 G G 的顶点数)。

【输入格式】

第1行:一个正数 n 2 n 80 n(2≤n≤80) ,表示图G的顶点总数。

第2行:一个整数,表示源点 v 0 v_0 v 0 V v_0∈V v 0 v_0 可以是图 G G 中任意一个顶点)。

第3至第 n + 2 n+2 行,用一个邻接矩阵 W W 给出了这个图。

【输出格式】

共包含 n 1 n-1 行,按照顶点编号从小到大的顺序,每行输出源点 v 0 v_0 到一个顶点的最短距离。每行的具体格式参照样例。

【输入样例】

5
1
0 2 - - 10
- 0 3 - 7
- - 0 4 -
- - - 0 5
- - 6 - 0

【输出样例】

(1 -> 2) = 2
(1 -> 3) = 5
(1 -> 4) = 9
(1 -> 5) = 9

【提示】

样例所对应的图如下:
在这里插入图片描述

【解析】

这题的难点在于读入。
我们可以巧妙利用C/C++的优势:
if(scanf("%d",&a))
可以用于判断a是否是整数。
如果输入的是-,自动返回-1,而且scanf()可以跳过空格。

读完后floyd就好了。

编Pascal的就没有那么幸运了。ヾ(•ω•`)o

【代码】

#pragma GCC optimize(3,"Ofast","inline")
#pragma G++ optimize(3,"Ofast","inline")

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

#define RI                 register int
#define re(i,a,b)          for(RI i=a; i<=b; i++)
#define ms(i,a)            memset(a,i,sizeof(a))
#define MAX(a,b)           (((a)>(b)) ? (a):(b))
#define MIN(a,b)           (((a)<(b)) ? (a):(b))

using namespace std;
 
typedef long long LL;
  
int const N=105;
int const inf=0x3f3f3f;

int n,v; 
int f[N][N];

int main() {
    scanf("%d%d",&n,&v);
    memset(f,inf,sizeof(f));
    for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) {
        int a;
        if(scanf("%d",&a)) f[i][j]=a;
            else f[i][j]=inf;
    }
    for(int k=1; k<=n; k++) for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) 
        f[i][j]=MIN(f[i][j],f[i][k]+f[k][j]);
    for(int i=1; i<=n; i++) if(i!=v) 
        printf("(%d -> %d) = %d\n",v,i,f[v][i]);
    return 0;
}
发布了106 篇原创文章 · 获赞 156 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/Ljnoit/article/details/105357048