洛谷 P1656 炸铁路 - SPFA

2023-12-04 04:04
文章标签 spfa 洛谷 铁路 p1656

本文主要是介绍洛谷 P1656 炸铁路 - SPFA,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 炸铁路
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
  • 题意解析
  • 思路
  • CODE



炸铁路

题目描述

A 国派出将军 uim,对 B 国进行战略性措施,以解救涂炭的生灵。

B 国有 n n n 个城市,这些城市以铁路相连。任意两个城市都可以通过铁路直接或者间接到达。

uim 发现有些铁路被毁坏之后,某两个城市无法互相通过铁路到达。这样的铁路就被称为 key road。

uim 为了尽快使该国的物流系统瘫痪,希望炸毁铁路,以达到存在某两个城市无法互相通过铁路到达的效果。

然而,只有一发炮弹(A 国国会不给钱了)。所以,他能轰炸哪一条铁路呢?

输入格式

第一行 n , m ( 1 ≤ n ≤ 150 n,m\ (1 \leq n\leq 150 n,m (1n150 1 ≤ m ≤ 5000 ) 1 \leq m \leq 5000) 1m5000),分别表示有 n n n 个城市,总共 m m m 条铁路。

以下 m m m 行,每行两个整数 a , b a, b a,b,表示城市 a a a 和城市 b b b 之间有铁路直接连接。

输出格式

输出有若干行。

每行包含两个数字 a , b a,b a,b,其中 a < b a<b a<b,表示 ⟨ a , b ⟩ \lang a,b\rang a,b 是 key road。

请注意:输出时,所有的数对 ⟨ a , b ⟩ \lang a,b\rang a,b 必须按照 a a a 从小到大排序输出;如果 a a a 相同,则根据 b b b 从小到大排序。

样例 #1

样例输入 #1

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

样例输出 #1

1 2
5 6


题意解析

  • 本题可抽象成以下意思:以某一点为源点a,删掉跟它连接的b点之间的路,如果这俩不能连通了,就算是答案。
  • 而不连通,这个似乎可以用并查集做,但是我在这用的是 S P F A SPFA SPFAa, b间的最短路,如果不存在了,说明不连通了。

思路

  • 初始化图,读入每一条边。
  • 两层循环枚举每个点,a始终比b小,如果两点之间有路那么就进行删路寻最短路。
    • 如果还是有最短路,那么这条边不是我们要找的;
    • 如果没有最短路了,那么这条边就是我们要找的,将其压入 v e c t o r vector vector 内。
  • 由于要从小到大排序输出,我们使用 s o r t ( ) sort() sort() 函数对 v e c t o r < p i i > vector<pii> vector<pii> 进行排序,然后输出。
    • s o r t ( ) sort() sort() 函数:有第三个参数,是一个比较器,用于决定排序的顺序, s o r t ( ) sort() sort() 函数本身从小到大排序。
      • 比较器返回一个 b o o l bool bool 类型的变量,用于表示排序时,第一个元素是否应该在第二个元素之前。
      bool compare(int a, int b) {return a > b; // 按照降序排序
      }
      

CODE

#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <queue>
#define ll long long
#define INF 0x3f3f3f3f using namespace std;typedef pair<int, int> pii; // 定义一个pair类型,用于存储两个整数vector<pii> path; // 存储所有的关键路
const int N = 160, M = 5010;
int n, m; // n是城市的数量,m是铁路的数量
int g[N][N], st[N]; // g是邻接矩阵,st用于标记城市是否已经被访问
int dist[N]; // dist[i]表示从起始城市到城市i的最短距离// 判断移除城市a和城市b之间的铁路后,是否还存在一条从城市a到城市b的路径
bool spfa(int a, int b){memset(dist, INF, sizeof dist); // 初始化所有城市的距离为无穷大dist[a] = 0; // 起始城市到自身的距离为0queue<int> q;q.push(a); // 将起始城市添加到队列中st[a] = true; // 标记起始城市已经被访问while(q.size()){auto t = q.front(); // 取出队列中的第一个城市q.pop();st[t] = false; // 标记该城市已经被访问for(int i = 1; i <= n; ++i){// 如果当前正在处理的是城市a和城市b之间的铁路,则跳过if(i == b && t == a) continue; // 如果找到了一条到达城市i的更短的路径,则更新dist[i]if(dist[i] > dist[t] + g[t][i]){dist[i] = dist[t] + g[t][i];// 如果城市i还没有被访问过,则将其添加到队列中if(!st[i]){q.push(i);st[i] = true;}}}}// 如果城市b无法到达,则返回true,否则返回falseif(dist[b] == INF) return true;else return false;
}int main(){cin >> n >> m; // 读取城市和铁路的数量memset(g, INF, sizeof g); // 初始化邻接矩阵while(m--){int a, b;scanf("%d%d", &a, &b); // 读取一条铁路的信息g[a][b] = g[b][a] = 1; // 更新邻接矩阵}// 对每一对城市进行检查,如果它们之间的铁路是关键路,则将其添加到path中for(int i = 1; i <= n; ++i)for(int j = i + 1; j <= n; ++j)if(g[i][j] != INF && spfa(i, j)){path.push_back({i, j});}sort(path.begin(), path.end()); // 对path进行排序// 输出所有的关键路for(int i = 0; i < path.size(); ++i){auto t = path[i];cout << t.first << ' ' << t.second << endl;}
}

这篇关于洛谷 P1656 炸铁路 - SPFA的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/452041

相关文章

poj 1511 Invitation Cards(spfa最短路)

题意是给你点与点之间的距离,求来回到点1的最短路中的边权和。 因为边很大,不能用原来的dijkstra什么的,所以用spfa来做。并且注意要用long long int 来存储。 稍微改了一下学长的模板。 stack stl 实现代码: #include<stdio.h>#include<stack>using namespace std;const int M

poj 3159 (spfa差分约束最短路) poj 1201

poj 3159: 题意: 每次给出b比a多不多于c个糖果,求n最多比1多多少个糖果。 解析: 差分约束。 这个博客讲差分约束讲的比较好: http://www.cnblogs.com/void/archive/2011/08/26/2153928.html 套个spfa。 代码: #include <iostream>#include <cstdio>#i

poj 3169 spfa 差分约束

题意: 给n只牛,这些牛有些关系。 ml个关系:fr 与 to 牛间的距离要小于等于 cost。 md个关系:fr 与 to 牛间的距离要大于等于 cost。 隐含关系: d[ i ] <= d[ i + 1 ] 解析: 用以上关系建图,求1-n间最短路即可。 新学了一种建图的方法。。。。。。 代码: #include <iostream>#include

poj 3255 次短路(第k短路) A* + spfa 或 dijkstra

题意: 给一张无向图,求从1到n的次短路。 解析: A* + spfa 或者 dijkstra。 详解见上一题:http://blog.csdn.net/u013508213/article/details/46400189 本题,spfa中,stack超时,queue的效率最高,priority_queue次之。 代码: #include <iostream>#i

poj 2449 第k短路 A* + spfa

poj 2449: 题意: 给一张有向图,求第k短路。 解析: A* + spfa。 一下转自:http://blog.csdn.net/mbxc816/article/details/7197228 “描述一下怎样用启发式搜索来解决K短路。 首先我们知道A*的基础公式:f(x)=g(x)+h(x);对h(x)进行设计,根据定义h(x)为当前的x点到目标点t所需要的实际距

高精度计算(代码加解析,洛谷p1601,p1303)除法待更新

目录 高精度加法 高精度减法 高精度乘法 高精度加法 我们知道在c++语言中任何数据类型都有一定的表示范围。当两个被加数很大时,正常加法不能得到精确解。在小学,我们做加法都采用竖式方法。那么我们也只需要按照加法进位的方式就能得到最终解。 8 5 6+ 2 5 5-------1 1 1 1 加法进位: c[i] = a[i] + b[i];if(c[i] >=

【AcWing】852. spfa判断负环

#include<iostream>#include<algorithm>#include<cstring>#include<queue>using namespace std;const int N= 1e5+10;int n,m;int h[N],w[N],e[N],ne[N],idx;int dist[N],cnt[N];//cnt存最短路径的边数bool st[N];v

洛谷 凸多边形划分

T282062 凸多边形的划分 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 先整一个半成品,高精度过两天复习一下补上 #include <iostream>#include <algorithm>#include <set>#include <cstring>#include <string>#include <vector>#include <map>

能量项链,洛谷

解释:  环形dp问题还是考虑将环拉直,可以参考我上一篇文章:环形石子合并 [2 3 5 10 2] 3 5 10 将环拉直,[]内是一个有效的区间,可以模拟吸收珠子的过程,         如[2 3 5] <=>(2,3)(3,5)    2是头,3是中间,5是尾 len >= 3:因为最后[2 10 2]是最小的可以合并的有效区间 len <= n + 1因为[2 3

透析SPFA算法(图例讲解)

SPFA算法是Bellman-Ford的队列优化,所以先介绍Bellman-Ford算法。        Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的。这时候,就需要使用其他的算法来求解最短路径,Bellman-