本来打算用SPFA的,但最后考虑到对Dijkstra算法还不是很熟悉, 所以最终还是决定用Dijstra算法做,
题目大意是求到机场的最小花费,其中有一站你可以选择坐商业线(其他都为经济线,商业线时间花费较少)。
我的做法是:
1、首先求出起点到所有点的最短距离并记录,再求出终点到所有点的最短距离并记录。
2、枚举所有商业线路,并更新答案即可。
3、最后需要输出整个路径,我的做法是根据所得到的不同结果,再求一次最短路径,然后输出即可。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn=510;
const int inf=1<<28;
struct Edge
{
int from;
int to;
int dist;
};
struct HeapNode
{
int d;
int u;
bool operator < (const HeapNode& a)const
{
return d>a.d;
}
};
struct Dijkstra
{
int n,m;
vector<Edge> edges;
vector<int> G[maxn];
bool vis[maxn];
int dis[maxn];
int pre[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});
m=edges.size();
G[from].push_back(m-1);
}
void OutputWay(int s,int e)
{
if(e==s)
{
printf("%d",e);
return;
}
OutputWay(s,pre[e]);
printf(" %d",e);
}
void dijkstra(int s)
{
priority_queue<HeapNode> Q;
for(int i=0;i<=n;i++)
dis[i]=inf;
dis[s]=0;
memset(vis,0,sizeof(vis));
Q.push((HeapNode){0,s});
while(!Q.empty())
{
HeapNode x=Q.top();
Q.pop();
int u=x.u;
if(vis[u])continue;
vis[u]=true;
for(int i=0;i<G[u].size();i++)
{
Edge e=edges[G[u][i]];
if(dis[e.to]>dis[u]+e.dist)
{
dis[e.to]=dis[u]+e.dist;
pre[e.to]=e.from;
Q.push((HeapNode){dis[e.to],e.to});
}
}
}
}
}dis;
struct Edge a[2050];
int dista[maxn],distb[maxn];
int main()
{
int m,M,n,s,e,cas=0;
while(scanf("%d%d%d",&n,&s,&e)!=EOF)
{
if(cas++>0)
printf("\n");
dis.Init(n);
scanf("%d",&m);
for(int i=0;i<m;i++)
{
int ita,itb,itc;
scanf("%d%d%d",&ita,&itb,&itc);
dis.AddEdge(ita,itb,itc);
dis.AddEdge(itb,ita,itc);
}
scanf("%d",&M);
for(int i=0;i<M;i++)
{
int ita,itb,itc;
scanf("%d%d%d",&ita,&itb,&itc);
a[i*2].from=ita;
a[i*2].to=itb;
a[i*2].dist=itc;
a[i*2+1].from=itb;
a[i*2+1].to=ita;
a[i*2+1].dist=itc;
}
dis.dijkstra(s);
for(int i=1;i<=n;i++)
dista[i]=dis.dis[i];
dis.dijkstra(e);
for(int i=1;i<=n;i++)
distb[i]=dis.dis[i];
int ans=dista[e],used=-1;
for(int i=0;i<2*M;i++)
{
int cost=dista[a[i].from]+a[i].dist+distb[a[i].to];
if(ans>cost)
{
ans=cost;
used=i;
}
}
if(used==-1)
{
dis.dijkstra(s);
dis.OutputWay(s,e);
printf("\n");
printf("Ticket Not Used\n");
printf("%d\n",ans);
}
else
{
dis.dijkstra(s);
dis.OutputWay(s,a[used].from);
printf(" ");
dis.dijkstra(a[used].to);
dis.OutputWay(a[used].to,e);
printf("\n");
printf("%d\n",a[used].from);
printf("%d\n",ans);
}
}
return 0;
}