题目链接:

http://codeforces.com/problemset/problem/208/C

C. Police Station

time limit per test:2 seconds
memory limit per test:256 megabytes
#### 问题描述
> The Berland road network consists of n cities and of m bidirectional roads. The cities are numbered from 1 to n, where the main capital city has number n, and the culture capital — number 1. The road network is set up so that it is possible to reach any city from any other one by the roads. Moving on each road in any direction takes the same time.
>
> All residents of Berland are very lazy people, and so when they want to get from city v to city u, they always choose one of the shortest paths (no matter which one).
>
> The Berland government wants to make this country's road network safer. For that, it is going to put a police station in one city. The police station has a rather strange property: when a citizen of Berland is driving along the road with a police station at one end of it, the citizen drives more carefully, so all such roads are considered safe. The roads, both ends of which differ from the city with the police station, are dangerous.
>
> Now the government wonders where to put the police station so that the average number of safe roads for all the shortest paths from the cultural capital to the main capital would take the maximum value.
#### 输入
> The first input line contains two integers n and m (2 ≤ n ≤ 100, ) — the number of cities and the number of roads in Berland, correspondingly. Next m lines contain pairs of integers vi, ui (1 ≤ vi, ui ≤ n, vi ≠ ui) — the numbers of cities that are connected by the i-th road. The numbers on a line are separated by a space.
>
> It is guaranteed that each pair of cities is connected with no more than one road and that it is possible to get from any city to any other one along Berland roads.
#### 输出
> Print the maximum possible value of the average number of safe roads among all shortest paths from the culture capital to the main one. The answer will be considered valid if its absolute or relative inaccuracy does not exceed 10 - 6.
#### 样例
> **sample input**
> 4 4
> 1 2
> 2 4
> 1 3
> 3 4
>
> **sample output**
> 1.000000000000

题意

给你n个点(编号为1到n),m条边的有向图(无环,无重边,每个点都与其他点连通),现在要在一个点上建一个警察局,一条边,只要有一端与警察局相连,它就是安全的路,否则它就是不安全的路,现在问在哪个点建警察局能使从1到n的每条最短路上平均的安全路的条数(sigma(每条最短路上的安全路条数)/不同的最短路的条数)最多

题解

首先跑一遍单源最短路求出所有最短路组成的DAG图g1,然后在DAG上dp两次,其中dp[i]表示从n到i的最短路条数,dp2[i]表示从1到i的最短路条数。

这样不同的最短路的条数就等于dp[1]或dp2[n];

由于只有100个点,所以我们暴力枚举在2到n-1哪个点设警察局(在起点和终点设的话,平均的安全路的条数刚好会等于1)。每个警察局只会影响到它的邻边,我们现在把邻边分为两类(在g1中),一类以x为终点的边,一类为以x为起点的边,枚举所有的边,对于第一类边(u,x),贡献值为dp2[u] * dp[x]。

对于第二类边(x,v),贡献值为dp2[x] * dp[v]。sigma(每条最短路上的安全路条数)=sigma(每条边的贡献值)。

所以最后的答案就是max(sigma_i(每条边的贡献值))/dp[1]。

(sigma_i表示第i条边设警察局时的sigma(每条边的贡献值),sigma表示求和符号)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#include<queue>
using namespace std; typedef long long LL;
const int maxn = 222; int n, m; vector<int> G[maxn];
//g1表示从1到n的所有最短路组成的DAG图。
vector<int> g1[maxn], g2[maxn]; int inq[maxn], d[maxn];
void spfa(int s) {
memset(d, 0x3f, sizeof(d));
queue<int> pq;
inq[s] = 0; d[s] = 0; pq.push(s);
while (!pq.empty()) {
int u = pq.front(); pq.pop();
inq[u] = 0;
for (int i = 0; i<G[u].size(); i++) {
int v = G[u][i];
if (d[v]>d[u] + 1) {
d[v] = d[u] + 1;
if (!inq[v]) inq[v] = 1, pq.push(v);
g2[v].clear();
g2[v].push_back(u);
}
else if (d[v] == d[u] + 1) {
g2[v].push_back(u);
}
}
}
} void get_g1() {
for (int u = 1; u <= n; u++) {
// printf("%d: ",u);
for (int i = 0; i<g2[u].size(); i++) {
int v = g2[u][i];
// printf("%d ",v);
g1[v].push_back(u);
}
// puts("");
}
} LL dp[maxn];//dp[i]表示从n到i之间的最短路数
LL dfs(int u) {
if (dp[u]) return dp[u];
for (int i = 0; i<g1[u].size(); i++) {
int v = g1[u][i];
dp[u] += dfs(v);
}
return dp[u];
} LL dp2[maxn]; //dp2[i]表示从1到i之间的最短路数
LL dfs2(int u) {
if (dp2[u]) return dp2[u];
for (int i = 0; i<g2[u].size(); i++) {
int v = g2[u][i];
dp2[u] += dfs2(v);
}
return dp2[u];
} LL solve() {
LL ret = dp[1];
for (int i = 2; i<n; i++) {
LL sum = 0;
for (int j = 0; j<g1[i].size(); j++) {
int v = g1[i][j];
sum += dp[v] * dp2[i];
}
for (int j = 0; j<g2[i].size(); j++) {
int v = g2[i][j];
sum += dp2[v] * dp[i];
}
ret = max(ret, sum);
}
return ret;
} int main() {
scanf("%d%d", &n, &m);
while (m--) {
int u, v; scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
spfa(1);
get_g1();
memset(dp, 0, sizeof(dp));
dp[n] = 1;
LL fenmu = dfs(1);
memset(dp2, 0, sizeof(dp2));
dp2[1] = 1;
dfs2(n);
LL fenzi = solve();
printf("%.12lf\n", fenzi*1.0 / fenmu);
return 0;
}

乱七八糟

统计安全边的时候各种奇葩的想法,组合数学没学好,硬伤orz。

Codeforces Round #130 (Div. 2) C - Police Station 最短路+dp的更多相关文章

  1. Codeforces Round #130 (Div. 2) C. Police Station

    题目链接:http://codeforces.com/contest/208/problem/C 思路:题目要求的是经过1~N的最短路上的某个点的路径数 /  最短路的条数的最大值.一开始我是用spf ...

  2. Codeforces Round #267 (Div. 2) C. George and Job(DP)补题

    Codeforces Round #267 (Div. 2) C. George and Job题目链接请点击~ The new ITone 6 has been released recently ...

  3. Codeforces Round #408 (Div. 2) D - Police Stations

    地址:http://codeforces.com/contest/796/problem/D 题目: D. Police Stations time limit per test 2 seconds ...

  4. Codeforces Round #130 (Div. 2)

    A. Dubstep 字符串模拟. string.find()用法 string str; size_t pos = str.find("WUB"); // 返回匹配的第一个位置 ...

  5. Codeforces Round #130 (Div. 2) A. Dubstep

    题目链接: http://codeforces.com/problemset/problem/208/A A. Dubstep time limit per test:2 secondsmemory ...

  6. Codeforces Round #244 (Div. 2) A. Police Recruits

    题目的意思就是找出未能及时处理的犯罪数, #include <iostream> using namespace std; int main(){ int n; cin >> ...

  7. Codeforces Round #408 (Div. 2) D. Police Stations(最小生成树+构造)

    传送门 题意 n个点有n-1条边相连,其中有k个特殊点,要求: 删去尽可能多的边使得剩余的点距特殊点的距离不超过d 输出删去的边数和index 分析 比赛的时候想不清楚,看了别人的题解 一道将1个联通 ...

  8. Codeforces Round #287 (Div. 2) E. Breaking Good 最短路

    题目链接: http://codeforces.com/problemset/problem/507/E E. Breaking Good time limit per test2 secondsme ...

  9. Codeforces Round #343 (Div. 2) C. Famil Door and Brackets dp

    C. Famil Door and Brackets 题目连接: http://www.codeforces.com/contest/629/problem/C Description As Fami ...

随机推荐

  1. html5,html5教程

    html5,html5教程 1.向后兼容 HTML5是这样被定义的:能向后兼容目前UA处理内容的方式.为了让语言更简单,一些老的元素和Attribute被舍弃.比如一些纯粹用于展现的元素(译注:即非语 ...

  2. 转:OpenCms 9.0.1汉化

    LHD私人汉化. 1.完成安装OpenCms 2.如果正确安装,在浏览器输入以下地址即可打开登录页面(默认账号/密码:Admin/admin) http://localhost:8080/opencm ...

  3. static local variable

    Putting the keyword static in front of a local variable declaration creates a special type of variab ...

  4. js 月历 时间函数 月份第一天 星期的判断

    返回值为0-6,其中返回值0为星期天:如同,php中的日期函数一样判断.

  5. Android EditText 不弹出输入法

    当第一次进入一个activity的时候  一般是第一个edittext是默认选中的,但是该死的软键盘也一起弹出来了 那是相当的不美观哈!(#‵′)凸.为此, 本大人就去寻找在刚进入这个activity ...

  6. jquery的prop()和attr()

    jQuery1.6以后prop()和attr()的应用场景如下: 第一原则:只添加属性名称该属性就会立即生效应该使用prop(); 第二原则:只存在true/false的属性应该使用prop(); 设 ...

  7. android----Java DES加密算法工具类

    DESUtil类 public class DESUtil { private static byte[] iv = {0x12, 0x34, 0x56, 0x78, (byte) 0x90, (by ...

  8. ASP.NET MVC如何实现自定义验证(服务端验证+客户端验证)

    ASP.NET MVC通过Model验证帮助我们很容易的实现对数据的验证,在默认的情况下,基于ValidationAttribute的声明是验证被使用,我们只需 要将相应的ValidationAttr ...

  9. wifi链接配置

    linux 命令行配置wlan无线网卡 无线网卡配置此页由Linux Wiki日(星期四) 09:28的工作基础上.本文介绍在Linux命令行界面中手动配置无线网卡的方法.目前流行的多数发行版都支持用 ...

  10. [译]rabbitmq 2.2 Building from the bottom: queues

    我对rabbitmq学习还不深入,这些翻译仅仅做资料保存,希望不要误导大家. You have consumers and producers under your belt, and now you ...