UVA 11374 - Airport Express

本文介绍了一种使用Dijkstra算法解决最短路径问题的方法,并提供了一个具体的实现案例。该案例包括读取输入数据、构建图结构、运行Dijkstra算法寻找最短路径,以及输出最短路径及其长度。

最短路的问题 用dijkstra就行。  RE了好久,要注意这是无向图。

 

#include

#include

#include

#include

#include

#define maxn 100001

using namespace std;

struct Edge

{

   int from,to,dist;

} a[11000];

struct heapnode

{

   int d,u;

   bool operator < (const heapnode &rhs) const

   {

       return d>rhs.d;

   }

};

int n,m,s,t;

vector edges;

vector G[maxn];

bool done[maxn];

int p[maxn],pre[maxn],pre1[maxn];

int f[maxn],g[maxn];

 


void init(int n)

{

   //this->n=n;

   for(int i = 0; i < n; i++)

       G[i].clear();

   edges.clear();

}

 

 

 

void Addedge(int from,int to,int dist)

{

   edges.push_back((Edge)

   {

       from,to,dist

   });

   int m = edges.size();

   G[from].push_back(m-1);

}

void dijkstra(int s,int *d,int *path)

{

   int INF = 1<<20;

   priority_queue Q;

   for(int i = 0; i <= n; i++)

       d[i] = INF;

   d[s] = 0;

   memset(done,0,sizeof(done));

   Q.push((heapnode)

   {

       0,s

   });

   while(!Q.empty())

   {

       heapnode x = Q.top();

       Q.pop();

       int u = x.u,fl=0;

       if(done[u]) continue;

       done[u]=true;

       for(int i = 0; i < G[u].size(); i++)

       {

           Edge& e = edges[G[u][i]];

           if(d[e.to]>d[u]+e.dist)

           {

               d[e.to] = d[u]+e.dist;

               p[e.to] = G[u][i];

               path[e.to] = u;

               Q.push((heapnode)

               {

                   d[e.to],e.to

               });

           }

       }

   }

}

 

 

 

int main()

{

   int t1,k,count=0;

   int fr,to,di;

   while(scanf("%d %d %d",&n,&s,&t)==3)

   {

       if(count)

       printf("\n");

       count++;

       scanf("%d",&m);

       memset(f,-1,sizeof(f));

       memset(g,-1,sizeof(g));

       memset(p,-1,sizeof(p));

       init(n);

       for(int i = 0; i < m; i++)

       {

           scanf("%d %d %d",&fr,&to,&di);

           Addedge(fr,to,di);

           Addedge(to,fr,di);

       }

       scanf("%d",&k);

       for(int i = 0; i < k; i++)

       {

           scanf("%d %d %d",&a[i].from,&a[i].to,&a[i].dist);

           a[k+i].from = a[i].to;

           a[k+i].to = a[i].from;

           a[k+i].dist = a[i].dist;

       }

       int p1[maxn],p2[maxn],l1,l2;

       dijkstra(s,f,pre);

       memset(p,-1,sizeof(p));

       dijkstra(t,g,pre1);

       int minx=1<<20,sign=-1;

       for(int i = 0; i < 2*k; i++)

       {

           if(minx > f[a[i].from]+g[a[i].to]+a[i].dist)

           {

               minx = f[a[i].from]+g[a[i].to]+a[i].dist;

               sign = i;

           }

       }

       if(minx > f[t])

           sign = -2;

       if(sign==-2||sign==-1)

       {

           int pr[maxn];

           int y=t,lp=0;

           pr[lp++] = t;

           while(y!=s)

           {

               pr[lp++] = pre[y];

               y = pre[y];

           }

           for(int x = lp-1; x>0; x--)

               printf("%d ",pr[x]);

           printf("%d\n",pr[0]);

           printf("Ticket Not Used\n");

           printf("%d\n",f[t]);

       }

       else

       {

           int pr[maxn],pr1[maxn];

           int y=a[sign].from,lp=0,lp1=0;

           pr[lp++] = a[sign].from;

           while(y!=s)

           {

               pr[lp++] = pre[y];

               y = pre[y];

           }

           int x = a[sign].to;

           pr1[lp1++] = x;

           while(x!=t)

           {

               pr1[lp1++] = pre1[x];

               x = pre1[x];

           }

           for(int x = lp-1; x>=0; x--)

               printf("%d ",pr[x]);

           for(int x = 0; x < lp1-1; x++)

               printf("%d ",pr1[x]);

           printf("%d\n",pr1[lp1-1]);

           printf("%d\n",a[sign].from);

           printf("%d\n",minx);

       }

 


   }

   return 0;

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值