题目描述:

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. linux组网笔记

    一直以为自己linux还说的过去,事实上已经跟不上日新月异的应用需要了. 现成文档都没法看,错太多.然而毕竟是多年积累,整理一个准确的文档还是能做到的. 本机ip设置: # static interf ...

  2. 关于JavaScript日期类型处理的总结

    在任何一门开发语言中,对日期时间类型的处理,必不可少也非常重要,长期以来对于JS的日期类型处理较为苍白.在这里做一个浅显的总结. Date 对象用于处理日期和时间.Date 对象用于处理日期和时间.D ...

  3. CSS学习总结

    CSS基础 简介 什么是CSS? CSS如何创建? 选择器 通用选择器 标签选择器 类选择器 ID选择器 属性选择器 后代选择器 子选择器 相邻元素选择器 伪类选择器 CSS样式 背景 文本 字体 链 ...

  4. HTML笔记<note2>

    文本标记 我是正常的文本段落 我是用b标记的加粗文本 我是用strong定义的强调文本 i标记的倾斜文本 em强调文本 del标记的删除线 del标记的下划线文本 特殊字符标记 显示 说明 空格&am ...

  5. <c:forEach items="${list}" var="tt" varStatus="status"> 的相关大小长度

    <c:forEach items="${list}" var="tt" varStatus="status"> ${status ...

  6. awake()和start()还有update(),fixedupdate()的差别

    1.首先看一下untiy官方对awake()和start()的定义 awake()和start()函数会在脚本加载后自动调用,awake()会先被调用,即使脚本未被调用.最好用来设置脚本之间的引用和初 ...

  7. 一起来学linux:NFS服务器搭建

    p { margin-bottom: 0.25cm; line-height: 120% } a:link { } nfs是network file system的缩写,作用在于让不同的网络,不同的机 ...

  8. HTTP Error 500.19 - Internal Server Error

    1.使用svn对项目进行管理 2.之前都是平安无事,忽然有一天报错:HTTP Error 500.19 - Internal Server Error,如图: 3.经过各种挣扎和求证,最后发现是项目. ...

  9. 使用ichartjs生成图表

    官网:http://www.ichartjs.com/ ichartjs 是一款基于HTML5的图形库.使用纯javascript语言, 利用HTML5的canvas标签绘制各式图形. ichartj ...

  10. Windows解决anaconda下双python版本安装TensorFlow

    首先,就是双版本anaconda的安装: 以前安装好的是python2.7版本,而TensorFlow的安装仅支持3.5版本的.但是自己本来的2.7版本又不想遗弃.所以安装双版本的: 在anacond ...