dijkstra可以求最长路吗?
查看原帖
dijkstra可以求最长路吗?
320697
AMIRIOX無暝楼主2021/1/14 16:53

惊奇地发现node里面写的是return this->dis < o.dis;小于可过, 正常dij不都是>吗? 很多题解说这个是最长路, 我直接傻掉, 为啥dij可以求最长路啊?

这题要 求出一个路径之和, 然后用100除以这个路径之和最小 也就是说这个路径之和要最大 那就是最长路了?

但是OI-Wiki说最长路径是NPC的

无权最长(简单)路径: 此问题不具有,是 NPC 的。区别在于,要保证子问题无关,即同一个原问题的一个子问题的解不影响另一个子问题的解。相关:求解一个子问题时用到了某些资源,导致这些资源在求解其他子问题时不可用。

我直接疑惑??? 这题求啥呢???

AC代码 但我完全不理解我写了啥 求大佬解释/kel

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;

const int maxn = 100010*2;

struct edge
{
    int to;
    double w; 
    int nxt;
    edge() { nxt = 0; }
} g[maxn];
int tot, head[maxn];
void addEdge(int u, int to, double w)
{
    g[++tot].to = to;
    g[tot].w = w;
    g[tot].nxt = head[u];
    head[u] = tot;
}

int vis[maxn];
double dis[maxn];
struct node
{
    int u;
    double dis;
    node(int _u, double _dis) : u(_u), dis(_dis) {}
    bool operator<(const node &o) const
    {
        return this->dis < o.dis;
    }
};

void dijkstra(int s)
{
    priority_queue<node> q;
    q.push(node(s, 1.0));
    memset(dis, 0x3f, sizeof(dis));
    memset(vis, 0, sizeof(vis));
    dis[s] = 1.0;
    while (!q.empty())
    {
        node u = q.top();
        q.pop();
        if (vis[u.u])
            continue;
        vis[u.u] = 1;
        for (int i = head[u.u]; i; i = g[i].nxt)
        {
            int y = g[i].to;
            if (dis[y] < dis[u.u] * g[i].w)
                dis[y] = dis[u.u] * g[i].w;
            if (!vis[y])
                q.push(node(y, dis[y]));
        }
    }
}
int main(void)
{
    int n, m, a, b;
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= m; i++)
    {
        int x, y;
        double v;
        scanf("%d %d %lf", &x, &y, &v);
        v = 1.0 - ((double)v) / 100.0;
        addEdge(x, y, v);
        addEdge(y, x, v);
    }
    scanf("%d %d", &a, &b);
    dijkstra(a);
    // cout << dis[b] << endl;
    printf("%.8lf", 100.0 / dis[b]);
    return 0;
}
2021/1/14 16:53
加载中...