题目描述:

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).

输出描述:

Print a single number — the answer to the problem. If the it is impossible to meet the conditions, print -1.

输入样例1:

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

输出样例1:

0

输入样例2:

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

输出样例2:

1

输入样例3:

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

输出样例3:

-1

题目解释:

有1-n共n个点,其中有些点之间有直达路径且路径长度都为1,现在你将输入s1,t1,d1和s2,t2,d2代表从s1到t1不能超过d1距离,从s2到t2不能超过d2距离,在满足这两个条件的情况下你会摧毁多余的路段,现在要求你摧毁尽量多的路段满足该条件,你要输出能摧毁的最多路段的数量。如果不能则输出-1.

题目分析:

这是一道很明显的多源最短路径问题,因为从s1到t1不能超过d1距离,从s2到t2不能超过d2距离,所以我们一定得知道从s1到t1以及从s2到t2的最短距离,如果其中一个的最短距离大于限定距离,则输出-1.否则,我们需要找s1到t1以及s2到t2的重复路径最多的路径,这样,总的s1到t1,s2到t2的距离会相对少,要摧毁的就会相对多。大概思路已经有了,接下来我们要解决的就是求多源最短路径的问题你,相信电脑前的ACMer一定听说或者学会了迪杰特斯拉和佛洛依德算法,也就是单源和多源最短路径算法,但是佛洛依德算法在求多源最短路径时的时间复杂度为O(n^3),这是一个很让人不能忍受的时间复杂度,对于本题的限定条件n=3000时,必定超时,也就是说,不能使用前面两种算法求多源最短路径。那么,我们该用什么方法呢?细心的你一定注意到了,两个点之间只要有路,路径长度必然为1,如此说来,两个有路的点最短路径为1,而相邻的点则通过有路且相邻的点距离+1即可,发现了没有?对于本题特殊的路径相同的情况下,其实我们可以用广度优先搜索(bfs)来求多源最短路径,保存每一个顶点的层数即可,层层求距离,因为每个点在每一次bfs中走且只走1次,因此,其时间复杂度为O(n^2),虽然还是那么不能令人满意,但对于本题的n<=3000来说,够用了。

接下来上AC代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <list>
#include <ctime>
using namespace std;
const int maxn = 3010;
bool vis[maxn];
int d[maxn][maxn],ceng[maxn];//ceng数组保存广度优先搜索的层数
vector <int> edge[maxn];//使用不定长数组vector,其中,每一个顶点i所在的行中d[i][j](j >= 0)保存的是有直接路径的顶点下标
//以每一个顶点为行坐标的数组存放其相邻点下标
void add(int x,int y)
{
    edge[x].push_back(y);//将y保存入edge[x][j]
    edge[y].push_back(x);//同理
}
//////////////////////////////
//广度优先搜索求每个点到其他点的最短路径长度
void bfs(int s)
{
    memset(vis,false,sizeof(vis));
    queue <int>qu;
    qu.push(s);
    vis[s] = true;
    ceng[s] = 0;
    d[s][s] = 0;
    int x,i;
    while (!qu.empty())
    {
        x = qu.front();
        qu.pop();
        for (i = 0; i < edge[x].size(); i++)
        {
            if(!vis[edge[x][i]])
            {
              ceng[edge[x][i]] = ceng[x] + 1;//层数等于父节点的层数+1
              d[s][edge[x][i]] = ceng[edge[x][i]];//距离起点的距离等于层数即可,因为每条路的权值都为1
              qu.push(edge[x][i]);
              vis[edge[x][i]] = true;/将该顶点标记为true,表示该顶点到起点的最短路径已经求出来了
            }
        }
    }
}
int main(void)
{
    int n,m,i,j,u,v,ans,s1,t1,d1,s2,t2,d2;
    scanf ("%d%d",&n,&m);
    for (i = 1; i <= m; i++)
    {
        scanf ("%d%d",&u,&v);
        add(u,v);
    }
    scanf ("%d%d%d%d%d%d",&s1,&t1,&d1,&s2,&t2,&d2);
    for (i = 1; i <= n; i++)
    {
        bfs(i);
    }

//只要s1到t1或s2到t2其中一个的最短路径大于限定条件,输出-1
    if(d[s1][t1] > d1 || d[s2][t2] > d2)
    {
        printf ("-1\n");
        return 0;
    }
    ans = d[s1][t1] + d[s2][t2];
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= n; j++)
        {

//这四个条件很关键,这是求重复最多的路径长度的,你可以画个图看一看,其中d[i][j]时s1到t1和s2到t2的重复路径,其实只要走一次就好~
            if(d[s1][i] + d[i][j] + d[j][t1] <= d1 && d[s2][i] + d[i][j] + d[j][t2] <= d2)
            {
                ans = min(ans,d[s1][i] + d[i][j] + d[j][t1] + d[s2][i] + d[j][t2]);
            }
            if(d[t1][i] + d[i][j] + d[j][s1] <= d1 && d[s2][i] + d[i][j] + d[j][t2] <= d2)
            {
                ans = min(ans,d[t1][i] + d[i][j] + d[j][s1] + d[s2][i] + d[j][t2]);
            }
            if(d[s1][i] + d[i][j] + d[j][t1] <= d1 && d[t2][i] + d[i][j] + d[j][s2] <= d2)
            {
                ans = min(ans,d[s1][i] + d[i][j] + d[j][t1] + d[t2][i] + d[j][s2]);
            }
            if(d[t1][i] + d[i][j] + d[j][s1] <= d1 && d[t2][i] + d[i][j] + d[j][s2] <= d2)
            {
                ans = min(ans,d[t1][i] + d[i][j] + d[j][s1] + d[t2][i] + d[j][s2]);
            }
        }
    }

//总路径数量减去最多的重复路径能完成条件的路径数量就是能删除的最多的路径
    printf ("%d\n",m - ans);

return 0;
}

Codeforces543BDestory Roads心得的更多相关文章

  1. 最小生成树:POJ1251-Jungle Roads(最小生成树的模板)

    POJ 1251 Jungle Roads >[poj原址:http://poj.org/problem?id=1251](http://poj.org/problem?id=1251) Des ...

  2. 我的MYSQL学习心得(一) 简单语法

    我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  3. NoSql数据库使用半年后在设计上面的一些心得

    NoSql数据库这个概念听闻许久了,也陆续看到很多公司和产品都在使用,优缺点似乎都被分析的清清楚楚.但我心里一直存有一个疑惑,它的出现究竟是为了解决什么问题? 这个疑惑非常大,为此我看了很多分析文章, ...

  4. 我的MYSQL学习心得(二) 数据类型宽度

    我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  5. 我的MYSQL学习心得(三) 查看字段长度

    我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  6. 我的MYSQL学习心得(四) 数据类型

    我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(五) 运 ...

  7. 我的MYSQL学习心得(五) 运算符

    我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  8. 我的MYSQL学习心得(六) 函数

    我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  9. 我的MYSQL学习心得(七) 查询

    我的MYSQL学习心得(七) 查询 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

随机推荐

  1. 三、Spring的面向切面

    Spring的面向切面 在应用开发中,有很多类似日志.安全和事务管理的功能.这些功能都有一个共同点,那就是很多个对象都需要这些功能.复用这些通用的功能的最简单的方法就是继承或者委托.但是当应用规模达到 ...

  2. centos安装openoffice服务

    第一步:yum install openoffice.org-brand openoffice.org-core openoffice.org-java-common xvfb openoffice. ...

  3. 对ajax请求的简单封装,操作更方便

    我这里的接口数据调用的js叫interface.js,接口路径管理的js叫webSiteControl.js /** * Created by l2776 on 2017/7/11. * 接口数据调用 ...

  4. dubbo的架构

    dubbo架构图如下所示: 节点角色说明: Provider: 暴露服务的服务提供方. Consumer: 调用远程服务的服务消费方. Registry: 服务注册与发现的注册中心. Monitor: ...

  5. Fastify 系列教程二 (中间件、钩子函数和装饰器)

    Fastify 系列教程: Fastify 系列教程一 (路由和日志) Fastify 系列教程二 (中间件.钩子函数和装饰器) 中间件 Fastify 提供了与 Express 和 Restify ...

  6. 如何通过写bat 安装Windows服务,本人亲测成功

    1. 安装的bat文件 @echo on color 2f mode con: cols=80 lines=25 @echo 请按任意键开始安装后台服务... pause cd /d %~dp0 Le ...

  7. css3中“渐变”兼容性解决方案

    这次是简单的谈一下我们常见的渐变在各个浏览器下的兼容性问题,算一个比较简单的问题. 我们熟知的浏览器有Chrome.Firefox.Opera.Safari以及ie系列.最基础的background: ...

  8. MongoDB基本命令行操作

    1. 连接MongoDB: Mongodb://username:password@hostname/dbname 2. 创建数据库: use dbname:如果数据库不存在则创建数据库,否则切换到指 ...

  9. python自动化运维五:paramiko

    p { margin-bottom: 0.25cm; line-height: 120% } a:link { } paramiko是基于python实现的SSH2远程安全连接,支持认证以及密钥方式, ...

  10. Redis环境搭建

    一.准备的安装包 windows虚拟机软件:VMware Workstation Pro 12 linux安装文件:CentOS-7-x86_64-Minimal-1511.iso 远程登录软件:pu ...