poj2449

题意:给定一个图,求起点到终点的第k短路。

分析:先用dijkstra从t反向寻找最短路。然后使用A*算法,把f(i)=g(i) + h(i)。h(i)就是i点到t的最短距离。当某点出队次数达到k次的时候,结果为该点的当前路程+该点到t的最短距离。(我没有判断不连通的情况)

为什么这样做是对的呢?我们这样来思考,如果不实用最短路,而只使用A*那么t第x次出队的结果即为第x短路的距离。继而可以想到,从第一个出队次数达到x的点,沿着最短路走到t,一定是第x短路。

说实话我也没有完全理解。

另外注意s==t的情况,据说k要++,不明白为啥。

View Code
#include <iostream>
#include
<cstdio>
#include
<cstdlib>
#include
<cstring>
#include
<queue>
usingnamespace std;

#define V 1005
#define E 1000005

int n, m, s, t, k;
#define typec int
// type of cost
const typec inf =0x3f3f3f3f;
// max of cost
typec cost[E], dist[V];
int e, pnt[E], nxt[E], head[V], prev[V], vis[V];
int pnt2[E], nxt2[E], head2[V], prev2[V], cost2[E];

struct pqnode
{
int v, dist;
pqnode(
int vv =0, typec cc =0) :
v(vv), dist(cc)
{
}
};

struct qnode
{
int v;
typec c;
qnode(
int vv =0, typec cc =0) :
v(vv), c(cc)
{
}
booloperator<(const qnode& r) const
{
return c > r.c;
}
};

booloperator<(const pqnode &a, const pqnode &b)
{
return a.dist + dist[a.v] > b.dist + dist[b.v];
}

void dijkstra(int n, constint src)
{
qnode mv;
int i, j, k, pre;
priority_queue
<qnode> que;
vis[src]
=1;
dist[src]
=0;
que.push(qnode(src,
0));
for (pre = src, i =1; i < n; i++)
{
for (j = head[pre]; j !=-1; j = nxt[j])
{
k
= pnt[j];
if (vis[k] ==0&& dist[pre] + cost[j] < dist[k])
{
dist[k]
= dist[pre] + cost[j];
que.push(qnode(pnt[j], dist[k]));
prev[k]
= pre;
}
}
while (!que.empty() && vis[que.top().v] ==1)
que.pop();
if (que.empty())
break;
mv
= que.top();
que.pop();
vis[pre
= mv.v] =1;
}
}

inline
void addedge(int u, int v, typec c)
{
pnt[e]
= v;
cost[e]
= c;
nxt[e]
= head[u];
head[u]
= e++;
}

inline
void addedge2(int u, int v, typec c)
{
pnt2[e]
= v;
cost2[e]
= c;
nxt2[e]
= head2[u];
head2[u]
= e++;
}

void input()
{
memset(head,
-1, sizeof(head));
memset(vis,
0, sizeof(vis));
memset(prev,
-1, sizeof(prev));
memset(head2,
-1, sizeof(head2));
memset(prev2,
-1, sizeof(prev2));
scanf(
"%d%d", &n, &m);
for (int i =0; i < n; i++)
dist[i]
= inf;
for (int i =0; i < m; i++)
{
int a, b, c;
scanf(
"%d%d%d", &a, &b, &c);
a
--;
b
--;
addedge2(a, b, c);
addedge(b, a, c);
}
scanf(
"%d%d%d", &s, &t, &k);
s
--;
t
--;
if (s == t)
k
++;
}

int astar()
{
memset(vis,
0, sizeof(vis));
priority_queue
<pqnode> pq;
pq.push(pqnode(s,
0));
while (!pq.empty())
{
pqnode pre
= pq.top();
pq.pop();
vis[pre.v]
++;
if (vis[pre.v] == k)
return pre.dist + dist[pre.v];
for (int i = head2[pre.v]; i !=-1; i = nxt2[i])
if (vis[pnt2[i]] <= k)
pq.push(pqnode(pnt2[i], pre.dist
+ cost2[i]));
}
return-1;
}

int main()
{
// freopen("t.txt", "r", stdin);
input();
dijkstra(n, t);
printf(
"%d\n", astar());
return0;
}
posted @ 2011-05-23 18:16  金海峰  阅读(1156)  评论(0编辑  收藏  举报