POJ2449 Remmarguts' Date

  • 题目大意:给定一张有向图,求某两点间的第k短路。

  • 思路:先用堆优dij处理出各点到终点的最短路距离,然后进行A*,当终点取出次数为k时,第k短路即已求出。

  • 非常要注意的一点是,如果s=t,那么k++。(因为这个不知道被坑了多少回…)

  • 代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn=1005;
struct edge
{
       int to,len;
       edge(int to=0,int len=0):to(to),len(len){}
};
struct node
{
       int id,cost;
       node(int id=0,int cost=0):id(id),cost(cost){}
       bool operator < (const node &a) const
       {
            return cost>a.cost;
       }
};
int n,m,s,t,k;
int dis[maxn];
vector<edge> g[maxn],rg[maxn];

void init()
{
     memset(dis,0,sizeof(dis));
     scanf("%d%d",&n,&m);
     while (m--)
     {
           int a,b,t;
           scanf("%d%d%d",&a,&b,&t);
           g[a].push_back(edge(b,t));
           rg[b].push_back(edge(a,t));
     }
     scanf("%d%d%d",&s,&t,&k);
     if (s==t)
       k++;
}

priority_queue<node> q;
bool vis[maxn];

void dijkstra(int s)
{
     memset(dis,0x3f,sizeof(dis));
     dis[s]=0;
     q.push(node(s,0));
     while (!q.empty())
     {
           node tmp=q.top();
           int h=tmp.id;
           q.pop();
           if (vis[h])
             continue;
           vis[h]=1;
           vector<edge>::iterator it;
           for (it=rg[h].begin();it!=rg[h].end();++it)
           {
               if (!vis[(*it).to] && dis[(*it).to]>dis[h]+(*it).len)
               {                    
                    dis[(*it).to]=dis[h]+(*it).len;
                    q.push(node((*it).to,dis[(*it).to]));
               }
           }
     }
}

struct atype
{
       int now,eva,w;
       atype (int now=0,int w=0):now(now),w(w)
       {
            eva=w+dis[now];
       }              
       bool operator < (const atype &a) const 
       {
            return eva>a.eva;
       }
};

int cnt=0,ans=0;
bool flag=0;
priority_queue<atype> aq;

void astar()
{
     aq.push(atype(s,0));
     while (!aq.empty())
     {
           atype tmp=aq.top();
           aq.pop();
           if (tmp.now==t)
           {
               cnt++;
               if (cnt==k)
               {
                   ans=tmp.w;
                   flag=1;
                   break;
               }
           }
           vector<edge>::iterator it;
           int h=tmp.now;
           for (it=g[h].begin();it!=g[h].end();++it)
           {
               int cost=(*it).len+tmp.w;
               atype b=atype((*it).to,cost);
               aq.push(b);
           }
     }
     if (flag)
       printf("%lld",ans);
     else
       puts("-1");   
}

int main()
{
    init();
    dijkstra(t);
    astar();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值