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;
}

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

[CF544D]Destroying Roads_最短路_bfs的更多相关文章

  1. CF Destroying Roads (最短路)

    Destroying Roads time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  2. Codeforces Round #302 (Div. 2) D. Destroying Roads 最短路

    题目链接: 题目 D. Destroying Roads time limit per test 2 seconds memory limit per test 256 megabytes input ...

  3. Codeforces 543B Destroying Roads(最短路)

    题意: 给定一个n个点(n<=3000)所有边长为1的图,求最多可以删掉多少条边后,图满足s1到t1的距离小于l1,s2到t2的距离小于l2. Solution: 首先可以分两种情况讨论: 1: ...

  4. Codeforces Round #302 (Div. 2) D. Destroying Roads 最短路 删边

    题目:有n个城镇,m条边权为1的双向边让你破坏最多的道路,使得从s1到t1,从s2到t2的距离分别不超过d1和d2. #include <iostream> #include <cs ...

  5. Codeforces Round #302 (Div. 2) D - Destroying Roads 图论,最短路

    D - Destroying Roads Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/544 ...

  6. POJ 3921 Destroying the bus stations 沿着最短路迭代加深搜索

    题目:给出一个图,问最少删除多少个点,使得从点1到点n经过的点数超过k个. 分析: 上网搜了一下,发现很多人用网络流做的,发现我不会.再后来看到这篇说网络流的做法是错的,囧. 后来发现点数有点少,直接 ...

  7. codeforces 544 D Destroying Roads 【最短路】

    题意:给出n个点,m条边权为1的无向边,破坏最多的道路,使得从s1到t1,s2到t2的距离不超过d1,d2 因为最后s1,t1是连通的,且要破坏掉最多的道路,那么就是求s1到t1之间的最短路 用bfs ...

  8. 图论--网络流--最小割 HDU 2485 Destroying the bus stations(最短路+限流建图)

    Problem Description Gabiluso is one of the greatest spies in his country. Now he's trying to complet ...

  9. Codeforces 543.B Destroying Roads

    B. Destroying Roads time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

随机推荐

  1. CI环境搭建-创建git

    添加如下配置:  上图说的需每次启动的即下面这个文件: 默认用户名.密码是admin/admin  创建代码仓库:  选择版本库:  使用方法: 1,创建一个文件夹  选择版本库地址:  也可以通过c ...

  2. 51 Nod 1475 建设国家 (优先队列+贪心)

    1475 建设国家  基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 小C现在想建设一个国家.这个国家中有一个首都,然后有若干个中间站,还有若干个城 ...

  3. 【csp模拟赛2】黑莲花--数据结构+数论

    没有什么能够阻挡,你对被阿的向往.天天 AK 的生涯,你的心了无牵挂. 虐过大佬的比赛,也曾装弱装逼.当你低头的瞬间,才发现旁边的人. 把你的四肢抬起来,使劲地往门上撞.盛开着永不凋零,黑莲花. —— ...

  4. 在docker容器中python3.5环境下使用DIGITS训练caffe模型

    ********* 此处使用的基础镜像为 nvcr.io/nvidia/digits:18.06,镜像大小为6.04GB,可从nvidia官方pull此镜像: 容器配置: CUDA:9.0 CUDNN ...

  5. Java String和hadoop的Text差异性比较

    Text类似于String,UTF-8编码.采用整型储存长度,最大长度为2GB. 补充编码知识: ASCII码 英语字母标点符号等256个字符,一个字节储存,取值0x00-0x7F; UNICODE编 ...

  6. 在iOS开发中使用icon font的方法

    http://iconfont.cn/help/iconuse.html 在开发阿里数据iOS版客户端的时候,由于项目进度很紧,项目里的所有图标都是用最平常的背景图片方案来实现.而为了要兼容普通屏与R ...

  7. springboot+shiro 跨域解决(OPTIONS)

    拦截器判断 拦截器截取到请求先进行判断,如果是OPTIONS请求的话,则放行 import com.alibaba.fastjson.JSON; import com.zp.demo.util.Jwt ...

  8. openapi and light-4j

    light-4j项目支持openapi规范,本文介绍一下参照相关demo做的上传功能. openapi.yaml,按照规范编写内容,/openapi/swagger可以查看对应的swagger页面,A ...

  9. jdbc结合commons-dbutils-1.6.jar做素材数据处理的例子

    前两个 insertTitle,insertOpening 是刚开始做的针对单一素材数据解析及写入的方法,后面一个 insertMaterial 是后期封装的一个可处理各种素材导入的方法,main方法 ...

  10. Winform运行外部控制台程序,并在程序结束后执行其他动作

    ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = @"程序名"; psi.Arguments = @&qu ...