题目描述:

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. admin的基础配置

    admin自定义配置 一.admin.py 我们知道在models.py文件中创建的数据表,一方面我们可以通过视图函数对其进行增删改查,一方面我们也可以通过admin进行,通常我们是通过admin的前 ...

  2. 如何升级laravel5.4到laravel5.5并使用新特性?

    如何升级laravel5.4到laravel5.5并使用新特性? 修改composer.json: "laravel/framework": "5.5.*", ...

  3. Maven Install指令构建时出现找不到符号

    检查引用的JRE编译的版本,可能由于JRE编译版本太低导致的  

  4. LINUX 笔记-watch命令

    命令格式:watch[参数][命令] 可以将命令的输出结果输出到标准输出设备,多用于周期性执行命令/定时执行命令 命令参数: -n或--interval  watch缺省每2秒运行一下程序,可以用-n ...

  5. [hihoCoder]无间道之并查集

    题目大意: #1066 : 无间道之并查集 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 这天天气晴朗.阳光明媚.鸟语花香,空气中弥漫着春天的气息……额,说远了,总之, ...

  6. Python数据库查询之组合条件查询-F&Q查询

    F查询(取字段的值) 关于查询我们知道有filter( ) ,values( ) , get( ) ,exclude( ) ,如果是聚合分组,还会用到aggregate和annotate,甚至还有万能 ...

  7. Arduino上传数据至贝壳物联并与FPGA进行交互

    本篇实现Arduino与FPGA交互,当然也没有什么新的协议,还是基于串口通讯,现在学一个串口通信基本上可以驱动大多数模块了,而且和各种单片机无缝数据交互,Arduino由于其强大的库函数支持,在实现 ...

  8. Kotlin——最详细的接口使用、介绍

    在Kotlin中,接口(Interface)的使用和Java中的使用方式是有很大的区别.不管是接口中的属性定义,方法等.但是定义方式还是相同的. 目录 一.接口的声明 1.接口的声明 关键字:inte ...

  9. 磨刀不误砍柴工!vs2010快捷键大全

    最常用的快捷键: VS2012变化的快捷键: 注释::VS2010是(Ctrl+E,C),VS2012是(Ctrl+K, Ctrl+C),实际操作,按住Ctrl键不放,先按K键,再按C键.相当于Ctr ...

  10. IIS下自定义错误页面配置的两种方式(亲测可行)--IIS服务器

    网站自定义错误页面的设置,大家应该都知道它的重要性……不多说,下面带大家一步步在IIS下设置网站自定义错误页面…… 1.首先进入你的网站主页,找到[错误页](注意是IIS下的错误页不是.NET错误页) ...