week14图论练习题--dijkstra、prim、kruskal

12 篇文章 0 订阅

这周代码源做的少,都在洛谷上刷图论

所以周报只能交这个了hh。。不过这周其实还练了一些差分,打算写在另一篇博客;

主要刷了dijkstra、prim和kruskal的一些题,因为好久没做最短路题了,所以刷的都是黄题绿题之类的,下个星期再把难度提一提

修复公路

题目背景

A 地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车。政府派人修复这些公路。

题目描述

给出 A 地区的村庄数 N N N,和公路数 M M M,公路是双向的。并告诉你每条公路的连着哪两个村庄,并告诉你什么时候能修完这条公路。问最早什么时候任意两个村庄能够通车,即最早什么时候任意两条村庄都存在至少一条修复完成的道路(可以由多条公路连成一条道路)。

输入格式

1 1 1 行两个正整数 N , M N,M N,M

下面 M M M 行,每行 3 3 3 个正整数 x , y , t x,y,t x,y,t,告诉你这条公路连着 x , y x,y x,y 两个村庄,在时间t时能修复完成这条公路。

输出格式

如果全部公路修复完毕仍然存在两个村庄无法通车,则输出 − 1 -1 1,否则输出最早什么时候任意两个村庄能够通车。

样例 #1

样例输入 #1

4 4
1 2 6
1 3 4
1 4 5
4 2 3

样例输出 #1

5

提示

1 ≤ x , y ≤ N ≤ 1 0 3 1\leq x, y\leq N \le 10 ^ 3 1x,yN103 1 ≤ M , t ≤ 1 0 5 1\leq M, t \le 10 ^ 5 1M,t105

挺水的,用并查集来存已经联通的村庄,记得要先给每条边按照时间先后排个序,这样当并查集中的连通块足够大的时候能够及时的输出

#include <bits/stdc++.h>
using namespace std;

int N, M;
int p[1005];
bool flag;

struct Edge
{
    int x, y;
    int t;
}edge[100005];

bool cmp(Edge A, Edge B)
{
    return A.t < B.t;
}

int find(int x)
{
    if(x != p[x]) return find(p[x]);
    else return x;
}


int main()
{
    cin >> N >> M;
    for(int i = 1; i <= M; i ++) {
        cin >> edge[i].x;
        cin >> edge[i].y;
        cin >> edge[i].t;
    }
    
    sort(edge + 1, edge + M + 1, cmp); //按时间排序
    
    for(int i = 1; i <= N; i ++) p[i] = i; //并查集初始化
    
    int cnt = 1; //记录已经有多少个村庄联通
    
    for(int i = 1; i <= M; i ++) {
        int x = edge[i].x, y = edge[i].y, t = edge[i].t;
        if(find(x) != find(y))
        {
            p[find(x)] = find(y);
            cnt ++;
        }
        
        if(cnt == N){cout << t; flag = true; break;}
    }
    
    if(!flag) cout << -1;
    return 0;
}

[USACO3.1]最短网络 Agri-Net

题目背景

Farmer John 被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。

题目描述

FJ 已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。

你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。每两个农场间的距离不会超过 1 0 5 10^5 105

输入格式

第一行农场的个数 N N N 3 ≤ N ≤ 100 3 \leq N \leq 100 3N100)。

接下来是一个 N × N N \times N N×N 的矩阵,表示每个农场之间的距离。理论上,他们是 N N N 行,每行由 N N N 个用空格分隔的数组成,实际上,由于每行 80 80 80 个字符的限制,因此,某些行会紧接着另一些行。当然,对角线将会是 0 0 0,因为不会有线路从第 i i i 个农场到它本身。

输出格式

只有一个输出,其中包含连接到每个农场的光纤的最小长度。

样例 #1

样例输入 #1

4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0

样例输出 #1

28

提示

题目翻译来自NOCOW。

USACO Training Section 3.1

也是要先按边权排序,优先使用更短的边,直到所有点都被联通再输出

#include <bits/stdc++.h>
using namespace std;

int N, cnt, ans;
int p[105];

struct Edge
{
    int a, b;
    int w;
}edge[100005];

bool cmp(Edge A, Edge B)
{
    return A.w < B.w;
}

int find(int x)
{
    if(x != p[x]) return find(p[x]);
    else return x;
}

int main()
{
    cin >> N;
    
    for(int i = 1; i <= N; i ++) {
        p[i] = i; //顺便把并查集初始化了
        for(int j = 1; j <= N; j ++) {
            int t;
            cin >> t;
            edge[++ cnt].a = i;
            edge[cnt].b = j;
            edge[cnt].w = t;
        } //每条边会存两次不过问题不大
    }
    
    sort(edge + 1, edge + cnt + 1, cmp);
    
    int sum = 1;  //记录已连接的农场
    for(int i = 1; i <= cnt; i ++) {
        int a = edge[i].a, b = edge[i].b, w = edge[i].w;
        
        if(find(a) != find(b))
        {
            p[find(a)] = find(b);
            sum ++;
            ans += w;
        }
        
        if(sum == N) break;
    }
    
    cout << ans;
    return 0;
}

[SCOI2005]繁忙的都市

题目描述

城市 C 是一个非常繁忙的大都市,城市中的道路十分的拥挤,于是市长决定对其中的道路进行改造。城市 C 的道路是这样分布的:城市中有 n n n 个交叉路口,有些交叉路口之间有道路相连,两个交叉路口之间最多有一条道路相连接。这些道路是双向的,且把所有的交叉路口直接或间接的连接起来了。每条道路都有一个分值,分值越小表示这个道路越繁忙,越需要进行改造。但是市政府的资金有限,市长希望进行改造的道路越少越好,于是他提出下面的要求:

  1. 改造的那些道路能够把所有的交叉路口直接或间接的连通起来。
  2. 在满足要求 1 的情况下,改造的道路尽量少。
  3. 在满足要求 1、2 的情况下,改造的那些道路中分值最大的道路分值尽量小。

任务:作为市规划局的你,应当作出最佳的决策,选择哪些道路应当被修建。

输入格式

第一行有两个整数 n , m n,m n,m 表示城市有 n n n 个交叉路口, m m m 条道路。

接下来 m m m 行是对每条道路的描述, u , v , c u, v, c u,v,c 表示交叉路口 u u u v v v 之间有道路相连,分值为 c c c

输出格式

两个整数 s , m a x s, \mathit{max} s,max,表示你选出了几条道路,分值最大的那条道路的分值是多少。

样例 #1

样例输入 #1

4 5
1 2 3
1 4 5
2 4 7
2 3 6
3 4 8

样例输出 #1

3 6

提示

数据范围及约定

对于全部数据,满足 1 ≤ n ≤ 300 1\le n\le 300 1n300 1 ≤ c ≤ 1 0 4 1\le c\le 10^4 1c104 1 ≤ m ≤ 1 0 5 1 \le m \le 10^5 1m105

一道最小生成树的裸题,比较无脑,kruskal

#include <bits/stdc++.h>
using namespace std;

//最小生成树裸题,无脑。。

int N, M;
int p[305];

struct Edge
{
    int a, b;
    int w;
}edge[100005];

bool cmp(Edge A, Edge B)
{
    return A.w < B.w;
}

int find(int x)
{
    if(x != p[x]) return find(p[x]);
    else return x;
}

int main()
{
    cin >> N >> M;
    
    for(int i = 1; i <= N; i ++) p[i] = i;
    
    for(int i = 1; i <= M; i ++) {
        int u, v, c;
        cin >> u >> v >> c;
        edge[i].a = u;
        edge[i].b = v;
        edge[i].w = c;
    }
    
    sort(edge + 1, edge + M + 1, cmp);
    
    int s = 0, Max = 0;  //记录已连接的路口数量,和最大边
    for(int i = 1; i <= M; i ++) {
        int a = edge[i].a, b = edge[i].b, w = edge[i].w;
        
        if(find(a) != find(b))
        {
            p[find(a)] = find(b);
            s ++;
            Max = max(Max, w);
        }
        
        if(s == N - 1) break;
    }
    
    cout << s << ' ' << Max;
    return 0;
}

[USACO09OCT]Heat Wave G

题目描述

有一个 n n n 个点 m m m 条边的无向图,请求出从 s s s t t t 的最短路长度。

输入格式

第一行四个正整数 n , m , s , t n,m,s,t n,m,s,t
接下来 m m m 行,每行三个正整数 u , v , w u,v,w u,v,w,表示一条连接 u , v u,v u,v,长为 w w w 的边。

输出格式

输出一行一个整数,表示答案。

样例 #1

样例输入 #1

7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1

样例输出 #1

7

提示

【数据范围】
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 2500 1\le n \le 2500 1n2500 1 ≤ m ≤ 6200 1\le m \le 6200 1m6200 1 ≤ w ≤ 1000 1\le w \le 1000 1w1000

【样例说明】
5 → 6 → 1 → 4 5 \to 6 \to 1 \to 4 5614 为最短路,长度为 3 + 1 + 3 = 7 3+1+3 = 7 3+1+3=7

有生成树裸题,自然要来一道dijkstra裸题,这两道就当做模板来复习一下,其实堆优化的dijkstra有蛮多细节需要注意的,比如说h数组要初始化-1。。PII有时候会爆int。。这个真的忘不掉了

#include <bits/stdc++.h>
using namespace std;

const int N = 2505, M = 6205;

typedef pair<int, int> PII;  //存一对序号和距离

priority_queue <PII, vector<PII>, greater<PII> > heap;

int h[N], e[2 * M], ne[2 * M], w[2 * M], idx;
int dist[N];
bool st[N];
//dijkstra标配打好先
int n, m, s, t;

void add(int a, int b, int c)
{
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;
}

void dijkstra(int s) //以s为起点求最短路
{
    memset(dist, 0x3f, sizeof dist);
    dist[s] = 0;
    
    heap.push({0, s});
    
    while(heap.size())
    {
        auto t = heap.top();
        heap.pop();
        
        int ver = t.second, distance = t.first;
        if(st[ver]) continue;
        st[ver] = true;
        
        for(int i = h[ver]; i != -1; i = ne[i]) {
            int j = e[i];
            if(dist[j] > distance + w[i])
            {
                dist[j] = distance + w[i];
                heap.push({dist[j], j});
            }
        }
    }
    
    return;
}


int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
    memset(h, -1, sizeof h);
    
    cin >> n >> m >> s >> t;
    for(int i = 1; i <= m; i ++) {
        int u, v, c;
        cin >> u >> v >> c;
        add(u, v, c);
        add(v, u, c);
    } //存双向边
    
    dijkstra(s);
    
    cout << dist[t];
    return 0;
}

公路修建

题目描述

某国有 n n n 个城市,它们互相之间没有公路相通,因此交通十分不便。为解决这一“行路难”的问题,政府决定修建公路。修建公路的任务由各城市共同完成。

修建工程分若干轮完成。在每一轮中,每个城市选择一个与它最近的城市,申请修建通往该城市的公路。政府负责审批这些申请以决定是否同意修建。

政府审批的规则如下:

  1. 如果两个或以上城市申请修建同一条公路,则让它们共同修建;
  2. 如果三个或以上的城市申请修建的公路成环。如下图,A 申请修建公路 AB,B 申请修建公路 BC,C 申请修建公路 CA。则政府将否决其中最短的一条公路的修建申请;
  3. 其他情况的申请一律同意。

一轮修建结束后,可能会有若干城市可以通过公路直接或间接相连。这些可以互相连通的城市即组成“城市联盟”。在下一轮修建中,每个“城市联盟”将被看作一个城市,发挥一个城市的作用。

当所有城市被组合成一个“城市联盟”时,修建工程也就完成了。

你的任务是根据城市的分布和前面讲到的规则,计算出将要修建的公路总长度。

输入格式

第一行一个整数 n n n,表示城市的数量。( n ≤ 5000 n \leq 5000 n5000

以下 n n n 行,每行两个整数 x x x y y y,表示一个城市的坐标。( − 1 0 6 ≤ x , y ≤ 1 0 6 -10^6 \leq x,y \leq 10^6 106x,y106

输出格式

一个实数,四舍五入保留两位小数,表示公路总长。(保证有惟一解)

样例 #1

样例输入 #1

4
0 0
1 2
-1 2
0 4

样例输出 #1

6.47

提示

修建的公路如图所示:

这是一道不那么水的生成树了,因为kruskal会被卡空间,对于边数非常多的稠密图,kruskal中把每条边都存下来的过程是非常费空间的,而prim只在更新距离的时候才会用到边长,可以现用现算,prim是每次把离树距离最近的点加到树上,再用新加的点去更新外界点到树的距离。我用的是堆优化版的prim,跟dijkstra很像,然后这题有个点特别有启示意义,就是double数组的memset不可以用0x3f,会变成非常小的数,double的无穷大要用0x7f

#include <bits/stdc++.h>
using namespace std;

/*仔细想想其实第二个条件是不可能成立的
所以其实就是求最小生成树,
不过不能kruskal。。
交了一发MLE了。。*/

/*
Prim算法优势: 稠密图, 尤其是完全图. 
因为在Kruskal算法中, 
必须事先求出所有边的长度才能对之排序. 
对于一个有5000节点的完全图, 
这样做空间开销是巨大的. 
而Prim只在更新点到树的距离时需要用到边长, 
因此对于这种给坐标的完全图, 可以现用现算
*/

//堆优化版的prim,跟dijkstra如出一辙啊
//不过不用存图了,爽。。。

/*
另一个坑
double 的无穷大要0x7f
int才用0x3f
卡我好久。。
*/

const int N = 5005;

typedef pair<double, int> PDI; //码的思维定式写了PII调不出来

priority_queue <PDI, vector<PDI>, greater<PDI> > heap;

int n;
int x[N], y[N];  //记录点坐标
double dist[N];  // 记录外界的点到树上的最短距离
bool st[N];      //判断点是否在树上
double ans;


double d(int a, int b) //求ab间距离
{
    double t;
    t = pow(pow(x[a] - x[b], 2) + pow(y[a] - y[b], 2), 0.5);
    return t;
}


void prim(int s) //以s为起点求最小生成树
{
    memset(dist, 0x7f, sizeof dist);
    dist[s] = 0;   //放到树上,距离为0
    
    heap.push({0, s});
    
    while(heap.size())
    {
        auto t = heap.top();
        heap.pop();
        
        double distance = t.first;
        int ver = t.second;
        
        if(st[ver]) continue;
        st[ver] = true;

        ans += distance; //到树上的这段距离需要修建公路
        
        //接下来重新计算外界点到树上的距离
        for(int i = 1; i <= n; i ++) {
            if(st[i]) continue; //在树上的别算
            
            double dist_new = d(ver, i);
            if(dist_new < dist[i])
            {
                dist[i] = dist_new;
                heap.push({dist[i], i});
            }
        }
    }
    
    return;
}


int main()
{
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> x[i] >> y[i];
    
    prim(1);
    
    cout << fixed << setprecision(2) << ans;
    return 0;
}

通往奥格瑞玛的道路

题目背景

在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量。

有一天他醒来后发现自己居然到了联盟的主城暴风城。

在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛。

题目描述

在艾泽拉斯,有 n n n 个城市。编号为 1 , 2 , 3 , … , n 1,2,3,\ldots,n 1,2,3,,n

城市之间有 m m m 条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量。

每次经过一个城市,都会被收取一定的过路费(包括起点和终点)。路上并没有收费站。

假设 1 1 1 为暴风城, n n n 为奥格瑞玛,而他的血量最多为 b b b,出发时他的血量是满的。如果他的血量降低至负数,则他就无法到达奥格瑞玛。

歪嘴哦不希望花很多钱,他想知道,在可以到达奥格瑞玛的情况下,他所经过的所有城市中最多的一次收取的费用的最小值是多少。

输入格式

第一行 3 3 3 个正整数, n , m , b n,m,b n,m,b。分别表示有 n n n 个城市, m m m 条公路,歪嘴哦的血量为 b b b

接下来有 n n n 行,每行 1 1 1 个正整数, f i f_i fi。表示经过城市 i i i,需要交费 f i f_i fi 元。

再接下来有 m m m 行,每行 3 3 3 个正整数, a i , b i , c i a_i,b_i,c_i ai,bi,ci 1 ≤ a i , b i ≤ n 1\leq a_i,b_i\leq n 1ai,bin)。表示城市 a i a_i ai 和城市 b i b_i bi 之间有一条公路,如果从城市 a i a_i ai 到城市 b i b_i bi,或者从城市 b i b_i bi 到城市 a i a_i ai,会损失 c i c_i ci 的血量。

输出格式

仅一个整数,表示歪嘴哦交费最多的一次的最小值。

如果他无法到达奥格瑞玛,输出 AFK

样例 #1

样例输入 #1

4 4 8
8
5
6
10
2 1 2
2 4 1
1 3 4
3 4 3

样例输出 #1

10

提示

对于 60 % 60\% 60% 的数据,满足 n ≤ 200 n\leq 200 n200 m ≤ 1 0 4 m\leq 10^4 m104 b ≤ 200 b\leq 200 b200

对于 100 % 100\% 100% 的数据,满足 n ≤ 1 0 4 n\leq 10^4 n104 m ≤ 5 × 1 0 4 m\leq 5\times 10^4 m5×104 b ≤ 1 0 9 b\leq 10^9 b109

对于 100 % 100\% 100% 的数据,满足 c i ≤ 1 0 9 c_i\leq 10^9 ci109 f i ≤ 1 0 9 f_i\leq 10^9 fi109,可能有两条边连接着相同的城市。

细节多到爆炸的一题,PII爆int我愣是找不出来,惯性思维唉,光是二分还不够,虽然二分已经够难想的了,,,还要把二分的初始边界尽量压缩,具体见代码吧

#include <bits/stdc++.h>
using namespace std;
/*
哎。时隔两天来debug
发现是pair里面又写成了PII
然后爆int了
我真的焯了
心态炸裂
那天de了巨久。。。
*/

/*
语文不好。。
要求的是
经过城市最多的一次
这次的各个费用中的最小值是多少
*/

/*
用的钱越多
越有可能在血量耗尽前到终点
所以具有单调性
对钱进行二分
每条边的收费都小于等于此值 
并且 
走到终点之后血量不会被扣光
check里用dijkstra跑一边检验可不可行
边权是耗血量
*/
const int N = 10005, M = 50005;

typedef pair<long long, int> PLI;

int h[N], e[2 * M], ne[2 * M], idx;
long long dist[N];
bool st[N];
long long c[2 * M], f[N]; //耗血量,耗钱量
int n, m;
long long b;
long long l, r, mid;


void add(int a, int b, long long w)
{
    e[idx] = b, ne[idx] = h[a], c[idx] = w, h[a] = idx ++;
}


void dijkstra(int s, long long mid)
{
    priority_queue <PLI, vector<PLI>, greater<PLI> > heap;
    memset(dist, 0x7f, sizeof dist);
    memset(st, 0, sizeof st);
    //long long用memset好像有点问题?....
    dist[s] = 0;
    heap.push({0, s});
    
    while(heap.size())
    {
        auto t = heap.top();
        heap.pop();
        long long distance = t.first;
        int ver = t.second;
        
        if(st[ver]) continue;
        st[ver] = true;
        
        for(int i = h[ver]; i != -1; i = ne[i]) {
            int j = e[i];
            if(f[j] > mid) continue;
            if(dist[j] > distance + c[i])
            {
                dist[j] = distance + c[i];
                heap.push({dist[j], j});
            }
        }
    }
    
}


bool check(long long mid)
{
    dijkstra(1, mid);
    if(dist[n] > b) return false; //耗血过多
    else return true;
}


int main()
{
    memset(h, -1, sizeof h);
    
    cin >> n >> m >> b;
    
    for(int i = 1; i <= n; i ++) {
        cin >> f[i];
        r = max(r, f[i]);
    }
    l = max(f[1], f[n]);
    
    for(int i = 1; i <= m; i ++) {
        int u, v; long long w;
        cin >> u >> v >> w;
        add(u, v, w);
        add(v, u, w);
    }
    
    
    //l, r的取值是有说法的
    //l是max(f[1], f[n])
    //r是max(f[1 ~ n])
    long long Max = r;
    while(l <= r)
    { //mid是每个点能接受的最大收费超过的点就不要了
        mid = (l + r) >> 1;
        if(check(mid)) r = mid - 1;
        else l = mid + 1;
    }
    
    if(!check(Max)) cout << "AFK";
    else cout << l;
    return 0;
}

电车

题目描述

在一个神奇的小镇上有着一个特别的电车网络,它由一些路口和轨道组成,每个路口都连接着若干个轨道,每个轨道都通向一个路口(不排除有的观光轨道转一圈后返回路口的可能)。在每个路口,都有一个开关决定着出去的轨道,每个开关都有一个默认的状态,每辆电车行驶到路口之后,只能从开关所指向的轨道出去,如果电车司机想走另一个轨道,他就必须下车切换开关的状态。

为了行驶向目标地点,电车司机不得不经常下车来切换开关,于是,他们想请你写一个程序,计算一辆从路口 A A A 到路口 B B B 最少需要下车切换几次开关。

输入格式

第一行有 3 3 3 个整数 N , A , B N,A,B N,A,B 2 ≤ N ≤ 100 , 1 ≤ A , B ≤ N 2 \leq N \leq 100, 1 \leq A,B \leq N 2N100,1A,BN),分别表示路口的数量,和电车的起点,终点。

接下来有 N N N 行,每行的开头有一个数字 K i K_i Ki 0 ≤ K i ≤ N − 1 0 \leq K_i \leq N-1 0KiN1),表示这个路口与 K i K_i Ki 条轨道相连,接下来有 K i K_i Ki 个数字表示每条轨道所通向的路口,开关默认指向第一个数字表示的轨道。

输出格式

输出文件只有一个数字,表示从 A A A B B B 所需的最少的切换开关次数,若无法从 A A A 前往 B B B,输出 − 1 -1 1

样例 #1

样例输入 #1

3 2 1
2 2 3
2 3 1
2 1 2

样例输出 #1

0

抽象题建图的典范,,只要懂得如何建图就很好过

#include <bits/stdc++.h>
using namespace std;

/*
不看题解不会系列
关键在建图。。
把每一个车站看成一个点
这个站相连的第一个车站建立一条边权为0的边
对于它所相连的其他车站
建立边权为1的边
太牛了。。。
然后随便用哪种最短路都行
*/
const int INF = 100000000;
const int N = 105, M = 10050;
int h[N], e[M], ne[M], w[M], idx;
int dist[N];
bool st[N];
int n, A, B;

typedef pair<int, int> PII;

void add(int a, int b, int c)
{
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;
}

void dijkstra(int s)
{
    priority_queue <PII, vector<PII>, greater<PII> > heap;
    for(int i = 1; i <= n; i ++) dist[i] = INF;
    dist[s] = 0;
    heap.push({0, s});
    
    while(heap.size())
    {
        auto t = heap.top();
        heap.pop();
        int distance = t.first, ver = t.second;
        
        if(st[ver]) continue;
        st[ver] = true;
        
        for(int i = h[ver]; i != -1; i = ne[i]) {
            int j = e[i];
            if(dist[j] > distance + w[i])
            {
                dist[j] = distance + w[i];
                heap.push({dist[j], j});
            }
        }
    }
}


int main()
{
    memset(h, -1, sizeof h);
    
    cin >> n >> A >> B;
    for(int i = 1; i <= n; i ++) {
        int k, r;
        cin >> k;
        if(!k) continue;
        cin >> r;
        add(i, r, 0);
        for(int j = 2; j <= k; j ++) {
            cin >> r;
            add(i, r, 1);
        }
    }
    
    dijkstra(A);
    if(dist[B] == INF) cout << -1;
    else cout << dist[B];
    return 0;
}

emm这里是8题,虽然要求一周写10题,但由于另外几题写的并不是这个专题的,所以不放在这篇博客里了,我打算下篇博客再一起整理出来,反正每周任务肯定会完成地。。。。。。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Silver_Bullet14

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值