CodeVS1183 泥泞的道路 解题报告【二分答案+SPFA最长路】
2017-10-22 19:15
459 查看
题目描述 Description
CS有n个小区,并且任意小区之间都有两条单向道路(a到b,b到a)相连。因为最近下了很多暴雨,很多道路都被淹了,不同的道路泥泞程度不同。小A经过对近期天气和地形的科学分析,绘出了每条道路能顺利通过的时间以及这条路的长度。
现在小A在小区1,他希望能够很顺利地到达目的地小区n,请帮助小明找出一条从小区1出发到达小区n的所有路线中(总路程/总时间)最大的路线。请你告诉他这个值。
输入描述 Input Description
第一行包含一个整数n,为小区数。
接下来n*n的矩阵P,其中第i行第j个数表示从小区i到小区j的道路长度为Pi,j。第i行第i个数的元素为0,其余保证为正整数。
接下来n*n的矩阵T,第i行第j个数表示从小区i到小区j需要的时间Ti,j。第i行第i个数的元素为0,其余保证为正整数。
输出描述 Output Description
写入一个实数S,为小区1到达n的最大答案,S精确到小数点后3位。
样例输入 Sample Input
3
0 8 7
9 0 10
5 7 0
0 7 6
6 0 6
6 2 0
样例输出 Sample Output
2.125
数据范围及提示 Data Size & Hint
【数据说明】
30%的数据,n<=20
100%的数据,n<=100,p,t<=10000
解题报告
题目要求一个最大的答案,那么我们考虑二分,显然这样的状态是合法的:
P1+P2+P3+...+PnT1+T2+T3+...+Tn>ans
我们把分母去掉,可以得到:
P1+P2+P3+...Pn>ans∗(T1+T2+T3+...+Tn)
移项可得:
P1−ans∗T1+P2−ans∗T2+P3−ans∗T3+...+Pn−ans∗Tn>0
考虑怎么在这样一个式子的基础上写check函数。
如果我们令一条边的边权为Pi−mid∗Ti,那么dis[n] 显然就存储了上述式子的值。而我们希望上面这个式子更大,因为这样就可以让ans更大,所以我们就跑最长路,判定dis[n]是否大于0就好了。
因为是最长路,还需要考虑正环的情况。因为正环可以让dis
无限大,所以正环一定是合法的。
最后这道题竟然不卡精度,eps=10−4就好了。
代码如下:
CS有n个小区,并且任意小区之间都有两条单向道路(a到b,b到a)相连。因为最近下了很多暴雨,很多道路都被淹了,不同的道路泥泞程度不同。小A经过对近期天气和地形的科学分析,绘出了每条道路能顺利通过的时间以及这条路的长度。
现在小A在小区1,他希望能够很顺利地到达目的地小区n,请帮助小明找出一条从小区1出发到达小区n的所有路线中(总路程/总时间)最大的路线。请你告诉他这个值。
输入描述 Input Description
第一行包含一个整数n,为小区数。
接下来n*n的矩阵P,其中第i行第j个数表示从小区i到小区j的道路长度为Pi,j。第i行第i个数的元素为0,其余保证为正整数。
接下来n*n的矩阵T,第i行第j个数表示从小区i到小区j需要的时间Ti,j。第i行第i个数的元素为0,其余保证为正整数。
输出描述 Output Description
写入一个实数S,为小区1到达n的最大答案,S精确到小数点后3位。
样例输入 Sample Input
3
0 8 7
9 0 10
5 7 0
0 7 6
6 0 6
6 2 0
样例输出 Sample Output
2.125
数据范围及提示 Data Size & Hint
【数据说明】
30%的数据,n<=20
100%的数据,n<=100,p,t<=10000
解题报告
题目要求一个最大的答案,那么我们考虑二分,显然这样的状态是合法的:
P1+P2+P3+...+PnT1+T2+T3+...+Tn>ans
我们把分母去掉,可以得到:
P1+P2+P3+...Pn>ans∗(T1+T2+T3+...+Tn)
移项可得:
P1−ans∗T1+P2−ans∗T2+P3−ans∗T3+...+Pn−ans∗Tn>0
考虑怎么在这样一个式子的基础上写check函数。
如果我们令一条边的边权为Pi−mid∗Ti,那么dis[n] 显然就存储了上述式子的值。而我们希望上面这个式子更大,因为这样就可以让ans更大,所以我们就跑最长路,判定dis[n]是否大于0就好了。
因为是最长路,还需要考虑正环的情况。因为正环可以让dis
无限大,所以正环一定是合法的。
最后这道题竟然不卡精度,eps=10−4就好了。
代码如下:
#include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=100; const double eps=1e-4; int p[N+5][N+5],t[N+5][N+5]; double w[N+5][N+5],dis[N*N+5]; bool flag[N*N+5]; int tim[N*N+5],n; int spfa(int s,int e) { queue<int>q; memset(dis,-0x3f,sizeof(dis)); memset(flag,false,sizeof(flag)); memset(tim,0,sizeof(tim)); dis[s]=0,flag[s]=true,tim[s]++; q.push(s); while(!q.empty()) { int u=q.front();q.pop(); flag[u]=false; for(int v=1;v<=n;v++) if(p[u][v]!=0&&dis[v]<dis[u]+w[u][v]) { dis[v]=dis[u]+w[u][v]; if(!flag[v]) { tim[v]++; q.push(v); flag[v]=true; if(tim[v]>e)return true; } } } return dis[e]>0; } int check(double mid) { memset(w,0,sizeof(w)); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)w[i][j]=p[i][j]-mid*t[i][j]; return spfa(1,n); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)scanf("%d",&p[i][j]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)scanf("%d",&t[i][j]); double lf=0,rg=10000; while(rg-lf>eps) { double mid=(lf+rg)/2.0; if(check(mid))lf=mid; else rg=mid; } printf("%.3lf",lf); return 0; }
相关文章推荐
- codevs 1183 泥泞的道路 图论,spfa判环,二分答案
- codevs 1183 泥泞的道路(二分答案+spfa验证)
- <二分答案+spfa验证>codevs 1183 泥泞的道路
- codevs 1183 泥泞的道路 最长路 解题报告
- [codevs1183]泥泞的道路(二分+正环)
- [WIKIOI1183]泥泞的道路[二分答案+SPFA]
- codevs 1183 泥泞的道路(spfa+二分答案)
- codevs 1183 泥泞的道路 二分+SPFA最长路
- CodeVS 1183 SPFA+二分答案 解题报告
- CodeVS1183 泥泞的道路 题解 【二分答案】【SPFA】
- 【CodeVS1183】泥泞的道路
- codevs1183 泥泞的道路
- Codevs 1183 泥泞的道路
- codevs1183 泥泞的道路(最短路)
- codevs 1316 文化之旅 SPFA 解题报告
- codevs1183 泥泞的道路 图论+奇怪的东西[四星]
- codevs 1183 泥泞的道路 01分数规划
- codevs1183 泥泞的道路
- [codevs 1183][泥泞的道路(二分+spfa)
- 【Codevs1183】泥泞的道路