您的位置:首页 > 其它

poj 2449 Remmarguts' Date(K短路)

2017-02-06 01:03 225 查看
题目地址:http://poj.org/problem?id=2449
思路:K短路模板,A*算法。估价函数=当前值+当前位置到终点的距离,即f(p)=g(p)+h(p),每次扩展估价函数值最小的一个。选择f(p)最小的点,若其为t,则计算其出队次数,次数等于k时,即为第k短路长度。

#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e3+50;
const int maxm=1e5+50;
const int INF=0x3f3f3f3f;
struct VNode
{
int to,next,w;
};
struct Node
{
int to,f,g;
bool operator <(const Node &rhs) const
{
if(rhs.f==f) return rhs.g<g;
else return rhs.f<f;
}
};
int S,T,K;
int dist[maxn];
int tot1,tot2,n,m;
int head1[maxm],head2[maxm];
VNode edge1[maxm],edge2[maxm];
void addEdge1(int u,int v,int w)
{
edge1[tot1].to=v,edge1[tot1].w=w;
edge1[tot1].next=head1[u],head1[u]=tot1++;
}
void addEdge2(int u,int v,int w)
{
edge2[tot2].to=v,edge2[tot2].w=w;
edge2[tot2].next=head2[u],head2[u]=tot2++;
}
void SPFA(int s,int head[],VNode e[])
{
int v[maxn];
queue<int> q;
memset(v,0,sizeof(v));
for(int i=1; i<=n; i++) dist[i]=INF;
v[s]=1,dist[s]=0,q.push(s);
while(!q.empty())
{
int now=q.front();
q.pop(),v[now]=0;
for(int i=head[now]; ~i; i=e[i].next)
{
int nt=e[i].to;
if(dist[nt]>dist[now]+e[i].w)
{
dist[nt]=dist[now]+e[i].w;
if(!v[nt])
{
v[nt]=1;
q.push(nt);
}
}
}
}
}
int A_Star(int s,int t,int k,int head[],VNode e[])
{
int cnt=0;
if(s==t) k++;
if(dist[s]==INF) return -1;
Node now;
now.to=s,now.g=0,now.f=now.g+dist[s];
priority_queue<Node> pq;
pq.push(now);
while(!pq.empty())
{
Node now=pq.top();
pq.pop();
if(now.to==t) cnt++;
if(cnt==k) return now.g;
for(int i=head[now.to]; ~i; i=e[i].next)
{
Node nt;
nt.to=e[i].to;
nt.g=now.g+e[i].w;
nt.f=nt.g+dist[nt.to];
pq.push(nt);
}
}
return -1;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
tot1=0,tot2=0;
memset(head1,-1,sizeof(head1));
memset(head2,-1,sizeof(head2));
for(int i=0; i<m; i++)
{
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
addEdge1(x,y,w);
addEdge2(y,x,w);
}
scanf("%d%d%d",&S,&T,&K);
SPFA(T,head2,edge2);
printf("%d\n",A_Star(S,T,K,head1,edge1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: