传送门:>Here<

题意:给出一张无向图(边权为1),并给出两对起点和终点以及距离:s1,t1,l1; s2,t2,l2; 要求删除尽量多的边,使得dis(s1,t1)<=l1, dis(s2,r2)<=l2

解题思路

  首先我们会发现,由于边权都为1,删去一些边,某两点间的最短路肯定会随着删的边越来越多而越来越长(捷径被删了)

  因此我们会发现,要让边删的尽量多,最好最后只剩下最短路,其它边都剩下。换句话说,如果两条最短路不相交,那么最后只会剩下孤零零的两条链

  于是我们会发现,我们可以初步得到一个答案:$M - d(s1,t1) - d(s2,t2)$

  但这有可能不是最优的答案——两条最短路有可能有重叠。重叠的部分越长,答案就会越大也就是更优。并且很容易证明,重叠肯定只有连续的一段,而不会有间断的两断——因为如果需要有两断的话肯定不如连起来变为一段来的优。所以可以$O(n^2)$枚举重叠部分,验证一下就好了

Code

  用SPFA预处理出任意两点间的距离,注意数组要开$N*N$

  教训:当出现莫名其妙的错误的时候,首先检查数组有没有开错——例如,int开成bool,开得太小等等

/*By QiXingzhi*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define r read()
#define Max(a,b) (((a)>(b)) ? (a) : (b))
#define Min(a,b) (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
const int MAXN = ;
const int MAXM = ;
const int INF = ;
inline int read(){
int x = ; int w = ; register int c = getchar();
while(c ^ '-' && (c < '' || c > '')) c = getchar();
if(c == '-') w = -, c = getchar();
while(c >= '' && c <= '') x = (x << ) +(x << ) + c - '', c = getchar(); return x * w;
}
int N,M,x,y,s1,t1,l1,s2,t2,l2,top,sp1;
int first[MAXM*],nxt[MAXM*],to[MAXM*],num_edge;
int d[MAXN][MAXN],inQ[MAXN],pre[MAXN],ans[MAXN],tmp[MAXN];
queue <int> q;
inline void add(int u, int v){
to[++num_edge] = v;
nxt[num_edge] = first[u];
first[u] = num_edge;
}
inline void SPFA(int s, int c){
for(int i = ; i <= N; ++i) d[i][c] = INF;
memset(inQ, , sizeof(inQ));
d[s][c] = ;
q.push(s);
int u,v;
while(!q.empty()){
u = q.front();q.pop();
inQ[u] = ;
for(int i = first[u]; i; i = nxt[i]){
v = to[i];
if(d[u][c] + < d[v][c]){
d[v][c] = d[u][c] + ;
if(!inQ[v]){
inQ[v] = ;
q.push(v);
}
}
}
}
}
int main(){
// freopen(".in","r",stdin);
N=r,M=r;
for(int i = ; i <= M; ++i){
x=r,y=r;
add(x, y), add(y, x);
}
s1=r,t1=r,l1=r;
s2=r,t2=r,l2=r;
for(int i = ; i <= N; ++i){
SPFA(i, i);
}
if(d[s1][t1] > l1 || d[s2][t2] > l2){ printf("-1"); return ; }
int Ans = M - d[s1][t1] - d[s2][t2];
if(Ans < ) Ans = ;
for(int i = ; i <= N; ++i){
for(int j = ; j <= N; ++j){
if(i == j) continue;
if(d[s1][i] + d[j][t1] + d[i][j] <= l1){
if(d[s2][i] + d[j][t2] + d[i][j] <= l2){
Ans = Max(Ans, M - (d[s1][i]+d[i][j]+d[j][t1]+d[s2][i]+d[j][t2]));
}
if(d[s2][j] + d[i][t2] + d[i][j] <= l2){
Ans = Max(Ans, M - (d[s1][i]+d[i][j]+d[j][t1]+d[s2][j]+d[i][t2]));
}
}
if(d[s1][j] + d[i][t1] + d[i][j] <= l1){
if(d[s2][i] + d[j][t2] + d[i][j] <= l2){
Ans = Max(Ans, M - (d[s1][j]+d[i][j]+d[i][t1]+d[s2][i]+d[j][t2]));
}
if(d[s2][j] + d[i][t2] + d[i][j] <= l2){
Ans = Max(Ans, M - (d[s1][j]+d[i][j]+d[i][t1]+d[s2][j]+d[i][t2]));
}
}
}
}
printf("%d", Ans);
return ;
}

Codeforces543 B. Destroying Roads的更多相关文章

  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 543.B Destroying Roads

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

  4. Codeforces Round #302 (Div. 1) B - Destroying Roads

    B - Destroying Roads 思路:这么菜的题我居然想了40分钟... n^2枚举两个交汇点,点与点之间肯定都跑最短路,取最小值. #include<bits/stdc++.h> ...

  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. [CF544] D. Destroying Roads

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

  7. B. Destroying Roads

    Destroying Roads 题目链接 题意 n个点,m条边每两个点之间不会有两个相同的边,然后给你两个起s1,s2和终点t1,t2; 求删除最多的边后满足两个s1到t1距离\(<=l1\) ...

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

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

  9. [CodeForces] 543B Destroying Roads

    脑洞+暴力. 因为边权是1,所以bfs一下,O(n^2)求任意两点间最短路,再枚举. ans最大是\(dis_{s1,t1}+dis_{s2,t2}\) 再考虑有公共边的情况,一定存在两个点 u, v ...

随机推荐

  1. Linux iostat 命令

    iostat 命令是 I/O statistics(输入/输出统计)的缩写,用来报告系统的 CPU 统计信息和块设备及其分区的 IO 统计信息.iostat 是 sysstat 工具集的一个工具,在 ...

  2. Centos7 下SVN迁移

    SVN迁移需要做如下操作: 1. 将原来的Repository导出 . #svnadmin dump 原有repos的目录路径 > dumpfile (不同服务器安装目录不同,根据具体情况调整) ...

  3. E. Superhero Battle

    链接 [https://codeforces.com/contest/1141/problem/E] 题意 怪物开始的生命值,然后第i分钟生命值的变化 问什么时候怪物生命值为非正 分析 有一个巨大的坑 ...

  4. hibernate设置二级缓存时报错java.lang.NoClassDefFoundError: org/hibernate/engine/jndi/JndiNameException

    错误提示大概意思是,没有类定义错误,就是找不到要使用的hibernate二级缓存管理引擎类.我在这用的是ehcache二级轻量级缓存,报错原因可能是导入的jar包版本和使用的hibernate框架核心 ...

  5. docker之导出、导入、数据搬迁

    docker 导出 导入有二种,一种是备份镜像,一种备份容器.数据搬迁,最简单粗暴就是直接COPY,volume的路径就行了. 一.导出导入镜像 #导出为tar docker save #ID or  ...

  6. python os模块详解

    一.Python os模块(Linux环境) 1.1 执行shell命令 os.system('cmd') 执行命令不保存结果 os.popen('command') 执行后返回结果,使用.read( ...

  7. Apache Tomcat® - Which Version Do I Want?

    Apache Tomcat® - Which Version Do I Want?http://tomcat.apache.org/whichversion.html

  8. Ubuntu 12.04 安装socks5代理服务器dante-server

    dante-server是一个很好的socks4/5代理服务器软件. 使用apt-get安装   1 apt-getinstall dante-server 添加一个用户   1 2 useradd ...

  9. PHP的优化建议(仅借鉴)

    转载: https://www.awaimai.com/1050.html 1 字符串 1.1 少用正则表达式 能用PHP内部字符串操作函数的情况下,尽量用他们,不要用正则表达式, 因为其效率高于正则 ...

  10. PHP开发编码规范

    (转载:https://blog.csdn.net/alexdream/article/details/2213313) 这些年来多从事Linux下PHP和C相关的开发,带过很多项目和团队,下面是根据 ...