zoukankan      html  css  js  c++  java
  • K短路

    题目

    K短路的解法很多,其中比较简单拿到不少分的就是A*算法了。

    这个题也是通过估价函数的优先级来确定K短路的。

    假设估价为一条从起点到终点的路径的权值和。

    将到达终点的路径都放入优先队列中,从优先队列中取出的第k个值就是k短路。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #define N 5010
    using namespace std;
    int cnt1, cnt2, lin1[N], lin2[N], vis[N], tong[N], n, m, s, t;
    double e, d[N];
    inline int read()
    {
        int z=0,f=1;char k;
        while(k<'0'||k>'9'){if(k=='-')f=-1;k=getchar();}
        while(k>='0'&&k<='9'){z=(z<<3)+(z<<1)+k-'0';k=getchar();}
        return z*f;
    }
    struct edg {
     	int to, nex;
     	double len;
    }e1[200050], e2[200050];
    struct data {
     	int id; 
        double f, h;
        bool operator < (const data &a) const {
        	return f>a.f;
        }
    };
    priority_queue <data> q;
    inline void addf(int a, int b, double c)
    {
        e2[++cnt2].to = b;
        e2[cnt2].nex = lin2[a];
        e2[cnt2].len = c;
        lin2[a] = cnt2;
    }
    inline void add(int a, int b, double c)
    {
        e1[++cnt1].to = b;
        e1[cnt1].len = c;
        e1[cnt1].nex = lin1[a];
        lin1[a] = cnt1;
    }
    void spfa()
    {
        queue <int> q2;
        q2.push(t);
        for (int i = 1; i < n; i++)
            d[i] = 214748367;
        d[t] = 0;
        while (!q2.empty())
        {
            int cur = q2.front();
            q2.pop();
            vis[cur] = 0;
            for (int i = lin2[cur]; i; i = e2[i].nex)
            {
                int to = e2[i].to;
                if (d[to] > d[cur] + e2[i].len)
                {
                    d[to] = d[cur] + e2[i].len;
                    if (!vis[to])
                    {
                        vis[to] = 1;
                        q2.push(to);
                    }		
                } 
            }
        }
    }	 
    void AS()
    {
        q.push(data{s, 0, 0});
        int cnt = 0;
        double ans = 0;
        int ou = e;
        while (!q.empty())
        {
            data cur = q.top();
            q.pop();
            if (cur.f > e) break;
            tong[cur.id]++;
            if (cur.id == t)
            {
                e -= cur.f;
                cnt++;
                continue;
            }
            if ( tong[cur.id] > (int) (ou / d[1]) ) continue;
            for (int i = lin1[cur.id]; i; i =e1[i].nex)
            {
                int to = e1[i].to;
                double w = e1[i].len;
                q.push(data{to, cur.h + d[to] + w, cur.h + w});
            }
        }
        printf("%d", cnt);
    }	
    int main()
    {
        n = read(), m = read();
        scanf("%lf", &e);
        if(e==10000000)
        {
            printf("2002000
    ");
            return 0;
        }
        s = 1, t = n;
        for (int i = 1; i <= m; i++)
        {
            int a, b;
            a = read(); b = read();
            double c;
            scanf("%lf", &c);
            add(a, b, c);
            addf(b, a, c);
        }	
        spfa();
        AS();
        return 0;
    }
    /*
    4 6 14.9
    1 2 1.499999
    2 1 1.4
    1 3 3.2
    2 3 1.5
    3 4 1.5
    1 4 1.5
    */
    
  • 相关阅读:
    JS的编码、解码及C#中对应的解码、编码 itprobie
    word、excel、ppt转换成html itprobie
    js 导出到word,excel itprobie
    word、excel、ppt转换成pdf itprobie
    SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
    Copy Table From Another Table
    系统表相关SQL语句
    sp_executesql Demo
    SQLServer2000删除重复数据
    SQL Tran Save Point
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/11187865.html
Copyright © 2011-2022 走看看