首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

URAL 1980 Road to Investor(2分+最短路)

2013-10-22 
URAL 1980 Road to Investor(二分+最短路)n个点m条边的无向图,每条路有固定的长度,然后有一个速度上限。要

URAL 1980 Road to Investor(二分+最短路)

n个点m条边的无向图,每条路有固定的长度,然后有一个速度上限。要求在T时间内能从1到达n,最少超速多少?

显然是二分答案然后求最短路。不过当二分枚举的超速很大而某条边的距离很小的时候,经过这条边的时间是会很小很小的,所以要将所有的时间单位扩大1e9倍,才不会丢失精度。。。

#include<algorithm>#include<iostream>#include<cstring>#include<fstream>#include<sstream>#include<cstdlib>#include<vector>#include<string>#include<cstdio>#include<bitset>#include<queue>#include<stack>#include<cmath>#include<map>#include<set>#define FF(i, a, b) for(int i=a; i<b; i++)#define FD(i, a, b) for(int i=a; i>=b; i--)#define REP(i, n) for(int i=0; i<n; i++)#define CLR(a, b) memset(a, b, sizeof(a))#define debug puts("**debug**")#define LL long long#define PB push_back#define MP make_pairusing namespace std;const double INF = 1e50;const int maxn = 10010;const double eps = 1e-7;struct Edge{    int from, to;    double dist;    Edge(){}    Edge(int a, int b, double c):from(a), to(b), dist(c){}};struct Heap{    double d;    int u;    Heap(){}    Heap(double d, int u):d(d), u(u){}    bool operator<(const Heap& rhs) const    {        return d > rhs.d;    }};map<int, int> mp;bool flag;struct Dijkstra{    int n, m;    vector<int> G[maxn];    vector<Edge> edges;    bool done[maxn];    double d[maxn];    int p[maxn];    void init(int n)    {        this->n = n;        REP(i, n+1) G[i].clear();        edges.clear();    }    void add(int a, int b, double c, int id)    {        Edge e1 = Edge(a, b, c), e2 = Edge(b, a, c);        edges.PB(e1), edges.PB(e2);        m = edges.size();        G[a].PB(m-2), G[b].PB(m-1);        if(!flag) mp[m-2] = mp[m-1] = id;    }    void dijkstra(int s)    {        priority_queue<Heap> q;        REP(i, n+1) d[i] = INF;        d[s] = 0; CLR(done, 0);        q.push(Heap(0, s));        while(!q.empty())        {            Heap x = q.top(); q.pop();            int u = x.u;            if(done[u]) continue;            done[u] = 1;            REP(i, G[u].size())            {                Edge e = edges[G[u][i]];                if(d[e.to] > d[u] + e.dist)                {                    d[e.to] = d[u] + e.dist;                    p[e.to] = G[u][i];                    q.push(Heap(d[e.to], e.to));                }            }        }    }    void getpath(int s, int t, vector<int>& path)    {        while(t != s)        {            path.PB(p[t]);            t = edges[p[t]].from;        }        reverse(path.begin(), path.end());    }}solver;int n, m;double T;struct E{    int u, v;    double s, l;}e[maxn];bool ok(double mid){    solver.init(n);    FF(i, 1, m+1) solver.add(e[i].u, e[i].v, e[i].l/(e[i].s+mid)*1000000000, i);    solver.dijkstra(1);    flag = 1;    return solver.d[n] <= T;}int main(){    while(~scanf("%d%d", &n, &m))    {        mp.clear();        flag = 0;        FF(i, 1, m+1) scanf("%d%d%lf%lf", &e[i].u, &e[i].v, &e[i].s, &e[i].l);        scanf("%lf", &T);        T *= 1000000000;        double L = 0, R = 1e8, M;        while(L + eps < R)        {            M = (L + R) / 2;            if(ok(M)) R = M;            else L = M;        }        printf("%.6lf ", L);        vector<int> path;        solver.getpath(1, n, path);        int nc = path.size();        printf("%d\n", nc);        REP(i, nc) printf("%d%c", mp[path[i]], i == nc-1 ? '\n' : ' ');    }    return 0;}


热点排行