D. Destroying Roads

题目大意

In some country there are exactly n cities and m bidirectional roads connecting the cities. Cities are numbered with integers from 1 to n. If cities a and b are connected by a road, then in an hour you can go along this road either from city a to city b, or from city b to city a. The road network is such that from any city you can get to any other one by moving along the roads.

You want to destroy the largest possible number of roads in the country so that the remaining roads would allow you to get from city s1 to city t1 in at most l1 hours and get from city s2 to city t2 in at most l2 hours.

Determine what maximum number of roads you need to destroy in order to meet the condition of your plan. If it is impossible to reach the desired result, print -1.

数据范围

The first line contains two integers n, m (1 ≤ n ≤ 3000, ) — the number of cities and roads in the country, respectively.

Next m lines contain the descriptions of the roads as pairs of integers ai, bi (1 ≤ ai, bi ≤ n, ai ≠ bi). It is guaranteed that the roads that are given in the description can transport you from any city to any other one. It is guaranteed that each pair of cities has at most one road between them.

The last two lines contains three integers each, s1, t1, l1 and s2, t2, l2, respectively (1 ≤ si, ti ≤ n, 0 ≤ li ≤ n).


题解

首先,保证了删掉的边最多,那就说明$s1$到$t1$和$s2$到$t2$都分别只有一条路径,不然的话我们还可以删掉更多的边。

接下来我们考虑,最终答案的形式。

必定是如下三种情况之一:

第一种,这两条路径互不相交。就是$s1$到$t1$,$s2$到$t2$。

第二种,存在一条公共路径,$l$到$r$,答案是$s1$到$l$,$l$到$r$,$r$到$t1$;和$s2$到$l$,$l$到$r$,$r$到$t2$。

最后一种是$s2$和$t2$调换,也就是$t2$到$l$,$l$到$r$,$r$到$s2$。

显然,每段路径都是最短路。

我们需要枚举$l$和$r$,也就是说我们需要多源最短路。

但是已知的算法最快也只能做到$n^2logn$,跑$n$遍堆优化$Dijkstra$。

好慢啊.....

诶,我们发现每条边的边权都相等,所以我们可以直接$bfs$。

因为边权都相等,所以每个点第一次到的时间戳就是距离。

然后枚举更新答案就好,不要忘记了第一种情况和判断是否超出了长度上限$l1$和$l2$。

代码

#include <bits/stdc++.h>#define N 3010 using namespace std;int head[N], to[N << 1], nxt[N << 1], tot;int dis[N][N];bool vis[N];queue<int > q;char *p1, *p2, buf[100000];#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000,stdin), p1 == p2) ? EOF : *p1 ++ )int rd() {int x = 0, f = 1;char c = nc();while (c < 48) {if (c == '-')f = -1;c = nc();}while (c > 47) {x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();}return x * f;
}inline void add(int x, int y) {to[ ++ tot] = y;nxt[tot] = head[x];head[x] = tot;
}void bfs(int x) {while (!q.empty())q.pop();memset(dis[x], 0x3f, sizeof dis[x]);memset(vis, false, sizeof vis);vis[x] = true;dis[x][x] = 0;q.push(x);while (!q.empty()) {int p = q.front(); q.pop();for (int i = head[p]; i; i = nxt[i]) {if (!vis[to[i]]) {dis[x][to[i]] = dis[x][p] + 1;vis[to[i]] = true;q.push(to[i]);}}}
}int main() {int n = rd(), m = rd();for (int i = 1; i <= m; i ++ ) {int x = rd(), y = rd();add(x, y), add(y, x);}int s1 = rd(), t1 = rd(), l1 = rd();int s2 = rd(), t2 = rd(), l2 = rd();for (int i = 1; i <= n; i ++ ) {bfs(i);}if(dis[s1][t1] > l1 || dis[s2][t2] > l2)puts("-1"), exit(0);int ans = dis[s1][t1] + dis[s2][t2];for (int i = 1; i <= n ; i ++ ) {for (int j = 1; j <= n; j ++ ) {int v1, v2;v1 = dis[s1][i] + dis[i][j] + dis[j][t1];v2 = dis[s2][i] + dis[i][j] + dis[j][t2];if(v1 <= l1 && v2 <= l2)ans = min(ans, v1 + v2 - dis[i][j]);v2 = dis[s2][j] + dis[j][i] + dis[i][t2];if(v1 <= l1 && v2 <= l2)ans = min(ans, v1 + v2 - dis[i][j]);}}printf("%d\n", m - ans);return 0;
}

小结:好题啊。对于一个没有思路的题,我们可以想一想最终答案的样子。如果有没有用上的条件,看看能不能通过那个条件来优化当前的不完美算法。

转载于:https://www.cnblogs.com/ShuraK/p/11240535.html

[CF544D]Destroying Roads_最短路_bfs相关推荐

  1. Codeforces 544D Destroying Roads

    链接:http://codeforces.com/problemset/problem/543/B B. Destroying Roads time limit per test:2 seconds ...

  2. [C] [最短路] 只有5行的算法:Floyd-Warshall

    终于学到求最短路了,终于来到我最喜欢的算法--Floyd-Warshall了!今天还有点小激动呢! 我喜欢它,当然是因为它逻辑十分简单咯!真的只有5行诶! Floyd-Warshall算法 题目描述 ...

  3. BZOJ4152 AMPPZ2014 The Captain(最短路)

    事实上每次走到横坐标或纵坐标最接近的点一定可以取得最优方案.于是这样连边跑最短路就可以了. #include<iostream> #include<cstdio> #inclu ...

  4. Codeforces.1051F.The Shortest Statement(最短路Dijkstra)

    题目链接 先随便建一棵树. 如果两个点(u,v)不经过非树边,它们的dis可以直接算. 如果两个点经过非树边呢?即它们一定要经过该边的两个端点,可以直接用这两个点到 u,v 的最短路更新答案. 所以枚 ...

  5. BZOJ1491: [NOI2007]社交网络(Floyd 最短路计数)

    Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 2343  Solved: 1266 [Submit][Status][Discuss] Descrip ...

  6. HDU1811 Rank of Tetris 拓扑排序+并查集 OR 差分约束最短路+并查集

    题目链接 题意:就是给你一堆关系,看能不能排出个确定的顺序 做法: 1. 拓扑排序+并查集 应该很容易想到的一种思路,大于小于建立单向边.对于相等的呢,就把他们缩成一个点.就用并查集缩成一个点就行了 ...

  7. E:By Elevator or Stairs? CF595 DP最短路

    题目链接 比赛的时候一看,这不是最短路吗,然后敲了一个最短路. 然后比赛完发现大家基本都写的dp,我真是个憨憨,dp3行 最短路就建个简单的图,dp就是从上一维转化过来就是了 优秀的dp: //#pr ...

  8. The Shortest Statement CodeForces - 1051F LCA+最短路

    太弱了... 一开始看到题感觉是跑一个最小生成树在上边进行LCA就行了,但是发现过不了样例,然后就是就想到了之前做过类似做法的题目,就是非生成树上的边最多只有21条,然后就那些边记录下来,通过每一条边 ...

  9. JZOJ #4722 跳楼机 (最短路模型的完美转化)

    题目描述: 给出$h,x,y,z$,求在$h$以内,$x,y,z$可以凑出多少个不同的数.$(1\leq{h}\leq{10^{18}},1\leq{x,y,z}\leq{10^5})$ 解题思路: ...

最新文章

  1. multiplexed pins
  2. android 默认光标大小设置,如何默认光标位置设置的EditText
  3. edge无法上网dns_如何在Microsoft Edge中通过HTTPS启用DNS
  4. jQuery中兄弟元素、子元素和父元素的获取
  5. js格式化xml并高亮显示关键字
  6. (6)机器学习_支持向量机
  7. opencv 梯度幅值_20、 OpenCV导数和梯度
  8. Boost.Asio使用总结
  9. 计算机事业单位简答题MAC
  10. 开源RPC框架Pigeon
  11. FA_MASS_ADDITIONS Interface Table 资产成批增加
  12. 分析APP的安装流程 API29
  13. 项目管理过程之进度控制
  14. EasyExcel锁定指定单元格 禁止表格复制
  15. P0.9COB小间距LED显示技术的优势。
  16. 为什么使用双亲委派机制以及如何破坏双亲委派
  17. Pixhawk飞控代码(2019.11.28)
  18. Matlab中set函数的使用
  19. 【玩转yolov5】请看代码之augment_hsv
  20. 常见网络故障排错思路

热门文章

  1. 网络流(3)——找到最小st-剪切
  2. struct和typedef struct的区别(转)
  3. ArcGIS Android工程迁移到其他电脑不能打开的问题
  4. 仿微信公众号后台管理-自定义菜单
  5. java 添加一个线程、创建响应的用户界面 。 演示示例代码
  6. sqlite 数据类型 全面
  7. 3 当某个应用的CPU使用达到100%,该怎么办?
  8. 8086的两种工作模式_Buck变换器工作原理
  9. 本地php后台密码恢复默认,找回wordpress后台管理密码的PHP脚本方法
  10. python list append tuple_Python之list、tuple、dict、set