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 ...
随机推荐
- CentOS 5.x版本升级PHP
#-----------------------------CentOS 5.x版本升级PHP------------------#! /bin/sh #1.关闭selinuxcp -rp /etc/ ...
- PeopleSoft Related Language Records
As we all know, PeopleSoft is capable of maintaining application data in multiple languages within t ...
- 【转】src与href属性的区别
ref:http://www.jb51.net/web/77258.html src和href之间存在区别,能混淆使用.src用于替换当前元素,href用于在当前文档和引用资源之间确立联系. src是 ...
- 获取屏幕分辨率(C/C++)
C/C++获取屏幕分辨率的方法 int main(int argc, char* argv[]) { // 需要添加头文件: // #include <Windows.h> system( ...
- POI中设置Excel单元格格式样式(居中,字体,边框等)
创建sheet什么的就不多说了,直接进入正题 HSSFCellStyle cellStyle = wb.createCellStyle(); 一.设置背景色: cellStyle.setFillF ...
- HTTP协议的URI及各种方法
每个Web服务器资源都有一个名字,这样客户端就可以说明他们感兴趣的资源是什么了,服务器资 源名被统称为:统一资源标识符(Uniform Resource Identifier, URI) Joe的五金 ...
- ASP.net UrlRewrite的防盗链功能
ASP.net中如何实现基于UrlRewrite的防盗链. ASP.net中最快实现UrlRewrite的方法这篇文章中说了如何做UrlRewrite,那只是一个最简单的应用 其实利用UrlRewri ...
- 直接拿来用!超实用的Java数组技巧攻略[转]
来自csdn http://www.csdn.net/article/2013-09-16/2816947-methods-for-java-arrays 本文分享了关于Java数组最顶级的11大方法 ...
- 通过HttpClient方式连接网络
xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:t ...
- 分享O'Reilly最新C语言指针数据
1.推荐书名 Understanding.and.Using.C.Pointers.pdf 2. 本书目录 Table of Content Chapter 1. Introduction Chapt ...