codevs1183泥泞的道路

SPFA+二分答案

开始做的时候,想直接跑图论,后来发现好像不对(不然数据范围怎么这么小)

但是显然要用到图论,机智的我就想到了二分答案。

考虑,假如有一个ans,那么如果存在length i / time i >=ans(i属于路径上的边),那么显然更优 ,则可发现问题可转换为如果一个答案更优,那么对于以 length i?ans*time i 为权值,重新构的图中,如果到达n的最长路不小于n,显然答案可以更优,只需要二分答案就可以了.另外如果有正权环显然是可以的  

唯独要注意的是,精度要求要满足题意,显然不能只分到第三位小数就停了,那样的话会gi

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int MAXN = 101;
int n;
int tim[MAXN][MAXN],s[MAXN][MAXN];
long double ju[MAXN][MAXN];
double dis[MAXN];
bool vis[MAXN];
int num[MAXN];//记录经过次数,判环
long double ans;
//二分答案+SPFA

queue<int>q;

inline int getint()
{
       int w=0,q=0;
       char c=getchar();
       while((c<‘0‘ || c>‘9‘) && c!=‘-‘) c=getchar();
       if (c==‘-‘)  q=1, c=getchar();
       while (c>=‘0‘ && c<=‘9‘) w=w*10+c-‘0‘, c=getchar();
       return q ? -w : w;
}

inline bool work(long double x){//跑最长路径
    for(int i=1;i<=n;i++) dis[i]=-0x7ffffff;//置为更小的负值
    // memset(dis,0,sizeof(dis));
    ans=x;

    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
        ju[i][j]=s[i][j]-x*tim[i][j];

    memset(vis,0,sizeof(vis));
    memset(num,0,sizeof(num));
    while(!q.empty()) q.pop();

    q.push(1); vis[1]=1; dis[1]=0;
    while(!q.empty()) {
    int u=q.front();
    q.pop(); vis[u]=0;
    for(int i=1;i<=n;i++)
        if(i!=u){
        if(dis[i]<dis[u]+ju[u][i]) {
            dis[i]=dis[u]+ju[u][i];
            if(!vis[i]) {
            vis[i]=1;
            q.push(i);
            num[i]++;
            if(num[i]>=n) return true;
            }
        }
        }
    }

    if(dis[n]>=0) return true;//存在更优的答案
    return false;
}

int main()
{
    n=getint();
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) s[i][j]=getint();
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) tim[i][j]=getint();

    long double l=0.00,r=10000.00;
    //long double jingdu=0.00001;
    long double jingdu=0.0001;
    while(r-l-jingdu>=0) {
    long double mid=l+(r-l)/2.0;
    if(work(mid)) l=mid;
    else r=mid;
    }
    printf("%.3lf",(double)l);
    return 0;
}
时间: 2024-12-16 10:37:36

codevs1183泥泞的道路的相关文章

codevs1183 泥泞的道路

题目描述 Description CS有n个小区,并且任意小区之间都有两条单向道路(a到b,b到a)相连.因为最近下了很多暴雨,很多道路都被淹了,不同的道路泥泞程度不同.小A经过对近期天气和地形的科学分析,绘出了每条道路能顺利通过的时间以及这条路的长度. 现在小A在小区1,他希望能够很顺利地到达目的地小区n,请帮助小明找出一条从小区1出发到达小区n的所有路线中(总路程/总时间)最大的路线.请你告诉他这个值. 输入描述 Input Description 第一行包含一个整数n,为小区数. 接下来n

【Codevs1183】泥泞的道路

Position: http://codevs.cn/problem/1183/ List Codevs1183 泥泞的道路 List Description Input Output Sample Input Sample Output HINT Solution Code Description CS有n个小区,并且任意小区之间都有两条单向道路(a到b,b到a)相连.因为最近下了很多暴雨,很多道路都被淹了,不同的道路泥泞程度不同.小A经过对近期天气和地形的科学分析,绘出了每条道路能顺利通过的

TYVJ P1577 泥泞的道路

题目链接:http://www.tyvj.cn/p/1577# P1577 泥泞的道路 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 公园中有n个景点,编号1~n,并由m条双向道路相连.由于昨天下雨,导致公园中的马路泥泞不堪,每条道路都有一个泥泞程度w.现有Q个游客依次向你求 助,想从景点X走到景点Y,他希望找到一条道路,使得经过道路泥泞程度的最大值尽量小.你能设计一个在线算法,帮他们找到方案吗? 输入格式 第一行两个正整数n和m,表示景点数和道路数.

1183 泥泞的道路

1183 泥泞的道路 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description CS有n个小区,并且任意小区之间都有两条单向道路(a到b,b到a)相连.因为最近下了很多暴雨,很多道路都被淹了,不同的道路泥泞程度不同.小A经过对近期天气和地形的科学分析,绘出了每条道路能顺利通过的时间以及这条路的长度. 现在小A在小区1,他希望能够很顺利地到达目的地小区n,请帮助小明找出一条从小区1出发到达小区n的所有路线中(总路程

codevs 1183 泥泞的道路

时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description CS有n个小区,并且任意小区之间都有两条单向道路(a到b,b到a)相连.因为最近下了很多暴雨,很多道路都被淹了,不同的道路泥泞程度不同.小A经过对近期天气和地形的科学分析,绘出了每条道路能顺利通过的时间以及这条路的长度. 现在小A在小区1,他希望能够很顺利地到达目的地小区n,请帮助小明找出一条从小区1出发到达小区n的所有路线中(总路程/总时间)最大的路线.请你告诉他这个值.

泥泞的道路

[题目描述] 有n个小区,并且任意小区之间都有两条单向道路(a到b,b到a)相连.因为最近下了很多暴雨,很多道路都被淹了,不同的道路泥泞程度不同.经过对近期天气和地形的科学分析,绘出了每条道路能顺利通过的时间以及这条路的长度. 现在某人在小区1,他希望能够很顺利地到达目的地小区n,请帮助他找出一条从小区1出发到达小区n的所有路线中(总路程/总时间)最大的路线,并告诉他这个值. [输入描述] 第一行包含一个整数n,为小区数. 接下来n*n的矩阵P,其中第i行第j个数表示从小区i到小区j的道路长度为

成功更容易光顾磨难和艰辛,正如只有经过泥泞的道路才会留下脚印

更新一下今天的学习进度:以后每天都会更新,倘若有啥感悟想说的话也会一起发出来,希望更多的人能和我一起坚持下去: 1.每天背诵50个英文单词,复习巩固了68个单词,进度:  1050/3486 2.<王者归来>两个月内读完,进度:395/1010 3.<人类简史>,进度:218/452

codevs 1183 泥泞的道路 (二分+SPFA+差分约束)

/* 二分答案(注意精度) 对于每一个答案 有(s1+s2+s3...)/(t1+t2+t3...)>=ans 时符合条件 这时ans有变大的空间 对于上述不等式如果枚举每一条路显得太暴力 化简一下变成 :s1-t1*ans+s2-t2*ans+s3-t3*ans...>=0 差分约束跑最长路 如果dis[n]>0 或者有正环 (开始这个忘掉了)ans就合法 */ #include<iostream> #include<cstdio> #include<cs

[codevs 1183][泥泞的道路(二分+spfa)

题目:http://dev.codevs.cn/problem/1183/ 分析:这个和最优比率生成树很像,都可以二分答案的,只不过判定方面一个是求是否有最短路径,一个是求是否有生成树.假设等待判定的是ans,那么我们可以把每条边的边权改成s[i][j]-ans*t[i][j],然后跑最长路.如果d[n]>=0,那么肯定就说明这个ans是可行的.但是要注意有可能最长路的时候可能出现正权环,那么可以脑补以下,无论是否环中是否包含n,但都可以多走这环几次使得目前的d很大很大,以至于走了一些负边到n时