题目
A traveler's map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.
Input Specification:
Each input file contains one test case. Each case starts with a line containing 4 positive integers N, M, S, and D, where N (<=500) is the number of cities (and hence the cities are numbered from 0 to N-1); M is the number of highways; S and D are the starting and the destination cities, respectively. Then M lines follow, each provides the information of a highway, in the format:
City1 City2 Distance Cost
where the numbers are all integers no more than 500, and are separated by a space.
Output Specification:
For each test case, print in one line the cities along the shortest path from the starting point to the destination, followed by the total distance and the total cost of the path. The numbers must be separated by a space and there must be no extra space at the end of output.
Sample Input
4 5 0 3 0 1 1 20 1 3 2 30 0 3 4 10 0 2 2 20 2 3 1 20
Sample Output
0 2 3 3 40
即求最短路线,并列时输出花费最小的。
代码的实现步骤是:输入,dijkstra,bfs。也是之前刷这类题时一直用的方法。
其实这类问题只要在dijkstra的过程中,增加一下需要的像总cost这类的信息,保留下parent,直接回溯就可以了……
代码:
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int MAX=0x3ffffff;
struct way_point //路线探测结构
{
int city; //到达的城市
int cost; //此时的开销
vector<int> road; //经过的城市
};
int main()
{
int n,m,s,d;
int dis[500]; //距离
int **way,**cost; //地图,花费
int i,j,c1,c2;
cin>>n>>m>>s>>d; //输入信息
way=new int*[n];
cost=new int*[n];
for(i=0;i<n;i++) //初始化地图
{
way[i]=new int [n];
cost[i]=new int [n];
dis[i]=MAX;
for(j=0;j<n;j++)
{
way[i][j]=MAX;
cost[i][j]=MAX;
}
}
for(i=0;i<m;i++) //输入路线和开销
{
cin>>c1>>c2;
cin>>way[c1][c2];
way[c2][c1]=way[c1][c2];
cin>>cost[c1][c2];
cost[c2][c1]=cost[c1][c2];
}
int flag[500]={0}; //是否用于松弛标记
int min,mint,td; //本轮用松弛点,次轮探测,距离
dis[d]=0; //B-F,速度较慢
flag[d]=1;
min=d;
while(min!=-1) //dijkstra
{
mint=-1;
td=MAX+1;
for(i=0;i<n;i++)
{
if(i!=min&&dis[min]+way[min][i]<dis[i])
dis[i]=dis[min]+way[min][i];
if(flag[i]==0&&dis[i]<td)
{
mint=i;
td=dis[i];
flag[i]=1;
}
}
min=mint;
}
way_point wt1,wt2,wtd; //临时点1,2,终点路线暂存
wtd.cost=MAX;
queue<way_point> way_test; //bfs队列
wt1.city=s;
wt1.cost=0;
wt1.road.push_back(s);
way_test.push(wt1);
while(!way_test.empty()) //bfs
{
wt1=way_test.front();
way_test.pop();
if(wt1.city==d)
{
if(wt1.cost<wtd.cost)
wtd=wt1;
}
else
{
for(i=0;i<n;i++)
{
if(way[wt1.city][i]!=MAX
&&dis[wt1.city]-way[wt1.city][i]==dis[i])
{
wt2.city=i;
wt2.cost=wt1.cost+cost[wt1.city][i];
wt2.road=wt1.road;
wt2.road.push_back(i);
way_test.push(wt2);
}
}
}
}
for(i=0;i<wtd.road.size();i++) //输出
cout<<wtd.road[i]<<" ";
cout<<dis[s]<<" "<<wtd.cost;
for(i=0;i<n;i++)
{
delete[] way[i];
delete[] cost[i];
}
delete[] way;
delete[] cost;
return 0;
}