题目链接:最短路径问题
这道题是最短路问题的进阶版本
在求最短路的基础上增加了求花费这一操作
就是如果说存在多条最短长度相同的路径,选择花费最少的那一条路
做法就是再定义一个存图的二维数组,只不过存的不是两点之间的距离了,而是两点之间的花费
我觉得这不得用两个队列吗??如果说存在两条路,它们的路径上的点除了起点和终点相同,其余的都不相同,一条路的前半部分花费多,后半部分花费少,另一条路的前半部分花费少,后半部分的花费多,总的花费是第一条路的少
还需要考虑的问题是如何确定多个最短路
之前的最短路一个选一个就行了
这道题就是在最短路代码的基础上添加以下代码,如果说找到了到下一个点更短的路,就更新那个点的最短距离和花费
如果说存在多条到这个点相同且最小的长度的路径,则更新这几条路的最小花费
for(int i=1;i<=n;i++){
if(!vis[i]&&dis[i]>mp[k][i].x+dis[k]){
dis[i]=mp[k][i].x+dis[k];
cost[i]=mp[k][i].y+cost[k];
que.push(Q(dis[i],i));
}else if(!vis[i]&&dis[i]==mp[k][i].x+dis[k]){
cost[i]=min(cost[i],mp[k][i].y+cost[k]);
//cout<<"cost["<<i<<"]="<<cost[i]<<endl;
}
}
关于细节性的问题:
这道题与模板题不同的地方是多了一个花费的问题
花费和路径上本质上是相同的,只不过优先级比路径低,不用单独再开一个二维数组存值了,可以选择定义结构体
自己的小问题是,在main函数里忘了调用Init()
改过之后提交总超时,在main函数开头加咒语如下:
ios::sync_with_stdio(false);
就能通过啦
AC代码:
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
typedef pair<int,int> Q;
const int maxn=1010;
const int INF=0x3f3f3f3f;
struct p{
int x;//距离
int y;//花费
};
p mp[maxn][maxn];
bool vis[maxn];
int dis[maxn];
int cost[maxn];
int n,m;
int Init(){
memset(vis,0,sizeof(vis));
memset(dis,INF,sizeof(dis));
memset(cost,INF,sizeof(cost));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j){
mp[i][j].x=0;
mp[i][j].y=0;
}
else{
mp[i][j].x=INF;
mp[i][j].y=INF;
}
}
}
}
int dijkstra(int a){
cost[a]=0;
dis[a]=0;
priority_queue<Q,vector<Q>,greater<Q> >que;
que.push(Q(dis[a],a));
while(!que.empty()){
Q q=que.top();
que.pop();
int k=q.second;
vis[k]=1;
for(int i=1;i<=n;i++){
if(!vis[i]&&dis[i]>mp[k][i].x+dis[k]){
dis[i]=mp[k][i].x+dis[k];
cost[i]=mp[k][i].y+cost[k];
que.push(Q(dis[i],i));
}else if(!vis[i]&&dis[i]==mp[k][i].x+dis[k]){
cost[i]=min(cost[i],mp[k][i].y+cost[k]);
//cout<<"cost["<<i<<"]="<<cost[i]<<endl;
}
}
}
}
int main(){
ios::sync_with_stdio(false);
while(cin>>n>>m){
if(n+m==0){
break;
}
Init();
int a,b,a1,b1,c,d;
for(int i=0;i<m;i++){
cin>>a1>>b1>>c>>d;
// mp[a][b].x=c;
// mp[a][b].y=d;
if(mp[a1][b1].x>c){
mp[a1][b1].x=c;
mp[b1][a1].x=c;
mp[a1][b1].y=d;
mp[b1][a1].y=d;
}else if(mp[a1][b1].x==c){
if(mp[a1][b1].y>d){
mp[a1][b1].y=d;
mp[b1][a1].y=d;
}
}
}
cin>>a>>b;
dijkstra(a);
// for(int i=1;i<=n;i++){
// cout<<dis[i]<<' '<<cost[i]<<'-'<<i<<endl;
// }
cout<<dis[b]<<' '<<cost[b]<<endl;
}
}