题目描述:

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. js 中 new fn与new fn()的区别

    在有些代码中,看见了let fn = new Fn()和let fn = new Fn,刚开始有些人或许和我一样感到些许疑惑,但潜意识的也会想到,这两者说不定就是一样的.没错!!在没有参数的情况下这两 ...

  2. 如何设置App的启动图

    如何设置App的启动图,也就是Launch Image? Step1 1.点击Image.xcassets 进入图片管理,然后右击,弹出"New Launch Image" 2.如 ...

  3. 五分钟上手Markdown

    Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式.------百度百科 话不多说,开始发车!总共10个标签,五分钟足矣,毕竟基本没难度 ...

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

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

  5. Vue源码后记-钩子函数

    vue源码的马拉松跑完了,可以放松一下写点小东西,其实源码讲20节都讲不完,跳了好多地方. 本人技术有限,无法跟大神一样,模拟vue手把手搭建一个MVVM框架,然后再分析原理,只能以门外汉的姿态简单过 ...

  6. Buy the Ticket(卡特兰数+递推高精度)

    Buy the Ticket Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...

  7. Disharmony Trees

    /* 写完这篇博客有很多感慨,过去一段时间都是看完题解刷题,刷题,看会题解,没有了大一那个时候什么都不会的时候刷题的感觉,这个题做了一天半,从开始到结束都是从头开始自己构思的很有感觉,找回到当初的感觉 ...

  8. Git Submodules are not SVN Externals

    一直在寻找Git跟TFS里面类似SVN Externals的替代方案, 今天终于找到了GIT里面的替代方案,在此做个备注 http://alexking.org/blog/2012/03/05/git ...

  9. spa(单页应用)中,使用history模式时,微信长按识别二维码在ios下失效的问题

    spa(单页应用,vue)中,使用history模式时,微信长按识别二维码在ios下失效的问题. 触发条件: spa单页应用: 路由模式 history 从其他页面跳转到带有微信二维码识别的页面(不是 ...

  10. 四:Java使用google的thumbnailator工具对图片压缩水印等做处理

    Thumbnailator是一个非常好的图片开源工具 使用方法: 在pom中加入以下jar包 <!-- 图片缩略图 图片压缩 水印 start--> <dependency>& ...