K短路-POJ-2449

K短路:
题目大意:有向边,求起点s 到终点t 的第K短路径。

Sample Input

2 2 
1 2 5 
2 1 4 
1 2 2

Sample Output
14
AC Code: SPFA+A*,优先队列
 
 
Memory:19012K    Time:313MS
#include <iostream> 
#include <cstdio> 
#include <cstring> 
#include <queue> 
#define Inf 0x7fffffff 
#define MaxE 100005 
#define MaxV 1005 
using namespace std; 
int N,M,S,T,K;
int dist[MaxV];
int vst[MaxV]; 
struct Node     //优先队列 
{  int v;
    int f,g; 
   bool operator <(const Node &a)const
    { 
     if(a.f==f)  return a.g<g; 
     return a.f<f;} 
}; 
struct Edge     //边 {  int to,next,w;
}edge[MaxE],edge1[MaxE]; 
int size;
int head[MaxV],head1[MaxV]; 
void InsertEdge(int from,int to,int w)  //插入边 
{  edge[size].to=to;
    edge[size].w =w ; 
   edge[size].next=head[from];
    head[from]=size; 
   edge1[size].to=from;
    edge1[size].w=w; 
   edge1[size].next=head1[to];
    head1[to]=size++;
} 
void spfa(int s)            //求 dist[MaxV] 
{  int i;
    int from,to;
    //cot[MaxV]; 
   queue<int> que; 
   for(i=1;i<=N;i++)
    {   dist[i]=Inf;vst[i]=0;//cot[i]=0;}         
   que.push(s),vst[s]=1;
    dist[s]=0; 
   while(!que.empty()) 
  {  from=que.front(),que.pop();
        vst[from]=0;//cot[from]++; 
     //if(cot[from]>=N)    return; 
      for(i=head1[from];i+1;i=edge1[i].next) 
      {   to=edge1[i].to; 
          if(dist[to]>dist[from]+edge1[i].w) 
          {   dist[to]=dist[from]+edge1[i].w; 
              if(!vst[to])
                    que.push(to),vst[to]=1; 
          }
               }
       } 
     return; 
} 
int a_star(int s,int t,int k) 
{   Node p,p1;
    priority_queue<Node> que; 
     int cnt=0;  //记录遍历终点的次数 
     int from,i; 
    if(s==t)    k++; 
    if(dist[s]==Inf)    return -1; 
   p.v=s,p.g=0,p.f=p.g+dist[p.v];
    que.push(p); 
   while(!que.empty()) 
   {   p=que.top(),que.pop();
        from=p.v; 
       if(from==t)
        {
           cnt++;
            if(cnt==k)  return p.g;
        }        
        for(i=head[from];i+1;i=edge[i].next) 
        {   p1.v=edge[i].to;
            p1.g=p.g+edge[i].w;
            p1.f=p1.g+dist[p1.v]; 
          que.push(p1); 
        } 
    } 
    return -1; 
} 
void init()     //初始化 
{   int i;
    int from,to,w;
    //scanf("%d%d",&N,&M); 
    size=0;
    memset(head,-1,sizeof(head));
    memset(head1,-1,sizeof(head1));  
    for(i=0;i<M;i++) 
       {scanf("%d%d%d",&from,&to,&w); InsertEdge(from,to,w);
    }     
    scanf("%d%d%d",&S,&T,&K); 
} 
int main() 
{
    //freopen("in.txt","r",stdin); 
    while(scanf("%d%d",&N,&M)!=EOF) 
    {   init(); 
        spfa(T); 
        printf("%d\n",a_star(S,T,K));
    } 
    return 0; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值