Codeforces Round #130 (Div. 2) C - Police Station 最短路+dp
题目链接:
http://codeforces.com/problemset/problem/208/C
C. Police Station
time limit per test:2 secondsmemory 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的更多相关文章
- Codeforces Round #130 (Div. 2) C. Police Station
题目链接:http://codeforces.com/contest/208/problem/C 思路:题目要求的是经过1~N的最短路上的某个点的路径数 / 最短路的条数的最大值.一开始我是用spf ...
- 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 ...
- Codeforces Round #408 (Div. 2) D - Police Stations
地址:http://codeforces.com/contest/796/problem/D 题目: D. Police Stations time limit per test 2 seconds ...
- Codeforces Round #130 (Div. 2)
A. Dubstep 字符串模拟. string.find()用法 string str; size_t pos = str.find("WUB"); // 返回匹配的第一个位置 ...
- Codeforces Round #130 (Div. 2) A. Dubstep
题目链接: http://codeforces.com/problemset/problem/208/A A. Dubstep time limit per test:2 secondsmemory ...
- Codeforces Round #244 (Div. 2) A. Police Recruits
题目的意思就是找出未能及时处理的犯罪数, #include <iostream> using namespace std; int main(){ int n; cin >> ...
- Codeforces Round #408 (Div. 2) D. Police Stations(最小生成树+构造)
传送门 题意 n个点有n-1条边相连,其中有k个特殊点,要求: 删去尽可能多的边使得剩余的点距特殊点的距离不超过d 输出删去的边数和index 分析 比赛的时候想不清楚,看了别人的题解 一道将1个联通 ...
- Codeforces Round #287 (Div. 2) E. Breaking Good 最短路
题目链接: http://codeforces.com/problemset/problem/507/E E. Breaking Good time limit per test2 secondsme ...
- 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 ...
随机推荐
- iPhone和iPad版本的分辨率a
- Delete PeopleSoft Query From the Database
There could be different reasons why a PeopleSoft developer would like to delete a query from the da ...
- j-query j-query
jQuery 1.安装:http://jquery.com/download/登陆这个jQuery下载2在.html文件的<head>标签中导入3 语法$(selector).acti ...
- 关于delphi XE7中的动态数组和并行编程(第一部分)
本文引自:http://www.danieleteti.it/category/embarcadero/delphi-xe7-embarcadero/ 并行编程库是delphi XE7中引进的最受期待 ...
- [习题]日历(Calendar)控件的障眼法(.Visible属性),使用时才出现?不用就消失?
原文出處 http://www.dotblogs.com.tw/mis2000lab/archive/2013/09/02/calendar_icon_visible.aspx [习题]日历(Cal ...
- Asp.net Form登陆认证的回顾学习
asp.net网站中,我最常用的就是Form认证了,在实现登陆时,利用Form认证实现用户的访问权限,哪些页面是可以匿名登陆,哪些页面需要认证后才能访问,哪些页面不能访问等等权限.我还可在登陆时,使用 ...
- Java 第一天
环境变量设置(以JDK1.7为例) CLASSPATH=.\;C:\Program Files\Java\jdk1.7.0_45\lib\dt.jar;C:\Program Files\Java\jd ...
- 如何排查java.lang.NoSuchMethodError错误
今天碰到一个java.lang.NoSuchMethodException的异常.基本解决思路是: 1.检查类所在jar包的版本是否正确. 2.检查是否有jar包冲突,比如加载了多个版本的xxx.ja ...
- unix的策略与机制
策略同机制分离,接口同引擎分离 Linux/Unix设计理念提供的一种机制不是策略.如果说机制是一种框架,那么,策略就是填充框架的一个个具体实施.机制提供的就是一种开放而宽松的环境,而策略就是在这个环 ...
- Union-SQL Server学习笔记
1.简单笔记 数据库查询语句中,通过UNION组合查询语句,可以将两个或更多查询的结果组合为单个结果集,该结果集包含组合查询中的所有查询的全部行. 利用UNION语句可以实现将不同数据表中符合条件,不 ...