【luoguP1730】最小密度路径

来源:互联网 发布:教育大数据应用 编辑:程序博客网 时间:2024/05/11 01:53


题目描述

给出一张有N个点M条边的加权有向无环图,接下来有Q个询问,每个询问包括2个节点X和Y,要求算出从X到Y的一条路径,使得密度最小(密度的定义为,路径上边的权值和除以边的数量)。

输入输出格式

输入格式:

第一行包括2个整数N和M。

以下M行,每行三个数字A、B、W,表示从A到B有一条权值为W的有向边。

再下一行有一个整数Q。

以下Q行,每行一个询问X和Y,如题意所诉。

输出格式:

对于每个询问输出一行,表示该询问的最小密度路径的密度(保留3位小数),如果不存在这么一条路径输出“OMG!”(不含引号)。

输入输出样例

输入样例#1:
3 31 3 52 1 62 3 621 32 3
输出样例#1:
5.0005.500

说明

1 ≤ N ≤ 10,1 ≤ M ≤ 100,1 ≤ W ≤ 1000,1 ≤ Q ≤ 1000




01分数规划裸题


首先考虑一下二分答案ans

如果有存在

ans > Σw[i] / cnt 即 Σ(w[i] - ans) / cnt < 0的情况

那么答案不合法,反之答案合法

然后spfa跑一跑就好了


代码:

#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<queue>using namespace std;typedef double DL;const int INF = 2147483647;const int maxn = 100;struct data{    int to,w;    DL v;};queue<int> Q;vector<data> e[maxn];int n,m;DL dis[maxn];bool exist[maxn],vis[maxn];DL ans[maxn][maxn];inline int getint(){    int ret = 0,f = 1;    char c = getchar();    while (c < '0' || c > '9')     {        if (c == '-') f = -1;        c = getchar();    }    while (c >= '0' && c <= '9')        ret = ret * 10 + c - '0',c = getchar();    return ret * f;}inline bool spfa(int s,int t){    for (int i = 1; i <= n; i++) dis[i] = INF;    dis[s] = 0;    Q.push(s);    while (!Q.empty())    {        int u = Q.front();        exist[u] = 0;        Q.pop();        for (int i = 0; i < e[u].size(); i++)        {            int v = e[u][i].to;            DL w = e[u][i].v;            if (dis[v] > dis[u] + w)            {                dis[v] = dis[u] + w;                if (!exist[v])                {                    Q.push(v);                    exist[v] = 1;                }            }        }    }    return dis[t] <= 0;}inline void rebuild(DL x){    for (int i = 1; i <= n; i++)        for (int j = 0; j < e[i].size(); j++)            e[i][j].v = (DL)(e[i][j].w) - x;}inline DL binary(int u,int v){    DL l = 0,r = 1000;    for (int i = 1; i <= 30; i++)    {        DL mid = (l + r) / 2;        rebuild(mid);        if (spfa(u,v))            r = mid;        else            l = mid;    }    return l;}inline bool dfs(int u,int t){    vis[u] = 1;    if (u == t) return 1;    for (int i = 0; i < e[u].size(); i++)    {        int v = e[u][i].to;        if (vis[v]) continue;        if (dfs(v,t)) return 1;    }    return 0;}int main(){    n = getint();    m = getint();    for (int i = 1; i <= m; i++)    {        int u = getint(),v = getint(),w = getint();        e[u].push_back((data){v,w});    }    for (int i = 1; i <= n; i++)        for (int j = 1; j <= n; j++)        {            if (i == j) continue;            memset(vis,0,sizeof(vis));            if (!dfs(i,j)) {ans[i][j] = -1; continue;}            ans[i][j] = binary(i,j);        }    int q = getint();    for (int i = 1; i <= q; i++)    {        int u = getint(),v = getint();        if (ans[u][v] == -1) printf("OMG!\n");        else printf("%0.3lf\n",ans[u][v]);    }    return 0;}


原创粉丝点击