您的位置:首页 > 其它

poj2449 Remmarguts' Date(K短路:A*算法)

2015-10-25 11:39 399 查看
题目链接:点击打开链接

题意描述:给定一张图,求从点s出发到点t的第k短路?

解题思路:A*算法

首先预处理使用Dijkstra求出从图中任意一点到点t的最短路径,然后使用A*算法求解即可

A*算法中g为从出发点s到当前所走过的实际距离,h为从当前点到目标点t的最短距离,每次我们扩展g+h最小的点即可

思考:本题我是用剪枝:记录一个maxdis表示第k短路的一个上界,使用下面更新,发现剪枝效果不是很大

if(tmp.ct == t&&tmp.g+(long long)k*can[t]<INF)
maxdis = min(maxdis,tmp.g+k*can[t]);
else if(tmp.ct!=t&&tmp.g+tmp.h+(long long)(k-1)*can[t]<INF)
maxdis = min(maxdis,tmp.g+tmp.h+(k-1)*can[t]);


代码:
#include <cstdio>
#include <cstring>
#include <queue>

#define MAXE 100010
#define MAXN 1010
#define INF 0x7fffffff

#define mem(a,b) memset(a,b,sizeof(a))

using namespace std;

int head1[MAXN], head2[MAXN], tol;
struct Edge{
int u;
int pre;
int v;
int next;
int value;
}e[MAXE];

void addEdge(int u, int v, int value)
{
e[tol].u = u; e[tol].value = value; e[tol].pre = head1[v]; head1[v] = tol;
e[tol].v = v; e[tol].next = head2[u]; head2[u] = tol++;
}
struct node{
int ct;
int g,h;
node(int _ct, int _g, int _h):ct(_ct), g(_g), h(_h){}
bool operator<(const struct node &b)const
{
return g+h > b.g+b.h;
}
};
int can[MAXN];
int n, m;
int s, t, k;
int maxdis;
bool vis[MAXN];
priority_queue<node> pq;

void dijkstra(){
for(int i = 0; i <= n; ++i)
{
can[i] = INF;
vis[i] = false;
}
int tdis;
while(!pq.empty()) pq.pop();
pq.push(node(t,0,0));
while(!pq.empty()){
node tmp = pq.top(); pq.pop();
if(vis[tmp.ct]) continue;
vis[tmp.ct]=true;
int u, v;
u = tmp.ct;
for(int i = head1[u]; i != -1; i = e[i].pre){
v = e[i].u;
tdis = e[i].value + tmp.g;
if(can[v] > tdis){
can[v] = tdis;
pq.push(node(v,tdis,0));
}
}
}
}
int a_star()
{
maxdis = INF;
if(s == t) k++;
if(!vis[s]) return -1;
while(!pq.empty()) pq.pop();
if(s==t)
pq.push(node(s,0,0));
else
pq.push(node(s,0,can[s]));
while(!pq.empty())
{
node tmp = pq.top(); pq.pop();
if(tmp.ct == t) k--;
if(k == 0) return tmp.g;
// if(tmp.g+tmp.h>maxdis) continue;

// if(tmp.ct == t&&tmp.g+(long long)k*can[t]<INF)
//     maxdis = min(maxdis,tmp.g+k*can[t]);
// else if(tmp.ct!=t&&tmp.g+tmp.h+(long long)(k-1)*can[t]<INF)
//     maxdis = min(maxdis,tmp.g+tmp.h+(k-1)*can[t]);
int u, v;
u = tmp.ct;
for(int i = head2[u]; i != -1; i = e[i].next)
{
v = e[i].v;
if(v != t && !vis[v]) continue;
//if(v==t&&tmp.g+e[i].value<=maxdis)
if(v==t)
pq.push(node(v,tmp.g+e[i].value,0));
//else if(v!=t&&tmp.g+e[i].value<=maxdis)
else
pq.push(node(v,tmp.g+e[i].value,can[v]));
}
}
return -1;
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF)
{
tol = 0;
mem(head1,-1); mem(head2,-1);

int u, v;
int value;
for(int i = 0; i < m; ++i)
{
scanf("%d%d%d", &u, &v, &value);
addEdge(u,v,value);
}
scanf("%d%d%d", &s, &t, &k);
dijkstra();
printf("%d\n",a_star());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: