|
带注释的代码
# include<iostream>
# include<cstdio>
# include<cmath>
# include<algorithm>
# include<cstring>
# include<queue>
using namespace std;
const int mn = 35;
const int inf = 0xfffffff;
struct edge{int to,dis,next;};
edge e1[mn*mn],e2[mn*mn];//e1存正向边,e2存反向边
int head1[mn],head2[mn],edge_max;
void add(int x,int y,int z)//加边
{
++edge_max;
e1[edge_max].to=y;
e1[edge_max].next=head1[x];
e1[edge_max].dis=z;
head1[x]=edge_max;
e2[edge_max].to=x;
e2[edge_max].dis=z;
e2[edge_max].next=head2[y];
head2[y]=edge_max;
}
struct node{
int id,f,g;//id为节点编号,g为估计函数
node(int id=0,int f=0,int g=0):id(id),f(f),g(g){}
bool operator <(const node &a)const{
if(f==a.f) return g>a.g;
return f>a.f;
}
};
int dis[mn];
bool vis[mn];
int n,st,en,maxn,k;
void spfa(int x)//预处理终点到各个节点到的最短路
{
queue<int> q;
for(int i=1;i<=n;i++)
dis[i]=inf;
dis[x]=0;
vis[x]=1;
q.push(x);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head2[u];i;i=e2[i].next)
{
if(dis[e2[i].to]>dis[u]+e2[i].dis)
{
dis[e2[i].to]=dis[u]+e2[i].dis;
if(!vis[e2[i].to])
{
vis[e2[i].to]=1;
q.push(e2[i].to);
}
}
}
}
}
void A_star(int x,int y){//第k短路模板
priority_queue<node>q;
q.push(node(x,0,0));
int cnt=0;
while(!q.empty()){
node h=q.top();q.pop();
if(h.id==y){
if(++cnt==k){//如果是第k次找到这个点,那么第k短路就是h.f
printf("%d ",h.f);
return ;
}
}
for(int i=head1[h.id];i;i=e1[i].next){
q.push(node(e1[i].to,h.g+e1[i].dis+dis[e1[i].to],h.g+e1[i].dis));
}
}
}
int main()
{
int x;
freopen("route.in","r",stdin);
freopen("route.out","w",stdout);
scanf("%d%d%d%d",&n,&st,&en,&maxn);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&x);
if(x==maxn || i==j)
continue;
add(i,j,x);//加边
}
spfa(en);//预处理,不要忘了。(血的教训)
for(k=1;k<=3;k++)
A_star(st,en);
return 0;
} |
|