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\n");
        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
*/
posted @ 2019-07-15 11:30  DAGGGGGGGGGGGG  阅读(523)  评论(0编辑  收藏  举报