Dijkstra算法(优先队列优化)
- 结构体 增加 花费项(cost)
- 增加 更新规则(同距离时选花费更少的)
#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
#include<climits>
using namespace std;
const int maxn=100001;
const int INF=INT_MAX;
struct Point{//优先队列的结点(编号、到源点的距离及花费)
int next;
int distance;
int cost;
bool operator <(Point x)const{
if(distance==x.distance)return cost>x.cost;
else return distance>x.distance;
}
Point(int n,int d,int c):next(n),distance(d),cost(c){}
Point(){}
};
struct Edge{//图的边
int to;
int distance;
int cost;
Edge(int t,int d,int c):to(t),distance(d),cost(c){}
Edge(){}
};
vector<Edge>graph[maxn];//图的邻接矩阵
int dis[maxn];
int cos[maxn];
void Dijkstra(int start,int n){
fill(dis+1,dis+n+1,INF);
fill(cos+1,cos+n+1,INF);
dis[start]=0;
cos[start]=0;
priority_queue<Point>myqueue;
myqueue.push(Point(start,0,0));
while(!myqueue.empty()){
int u=myqueue.top().next;//根据新选的u来更新距离
myqueue.pop();
for(int i=0;i<graph[u].size();i++){
int x=graph[u][i].to;
int y=graph[u][i].distance;
int z=graph[u][i].cost;
if((dis[u]+y<dis[x])||(dis[u]+y==dis[x]&&cos[u]+z<cos[x])){
dis[x]=dis[u]+y;
cos[x]=cos[u]+z;
myqueue.push(Point(x,dis[x],cos[x]));
}
}
}
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
if(n==0&&m==0)break;
memset(graph,0,sizeof(graph));
for(int i=0;i<m;i++){
int f,t,d,c;
scanf("%d%d%d%d",&f,&t,&d,&c);
graph[f].push_back(Edge(t,d,c));//无向边
graph[t].push_back(Edge(f,d,c));
}
int start,terminal;
scanf("%d%d",&start,&terminal);
Dijkstra(start,n);
printf("%d %d\n",dis[terminal],cos[terminal]);
}
return 0;
}