每条路除了距离,还有了费用。这样在我们计算每个点的最小距离d[]和最小费用时,优先保证距离最小d[i]>d[x]+maps[x][i][0],其次保证费用最小d[i]==d[x]+maps[x][i][0] && cost[i]>cost[x]+maps[x][i][1]。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<string>
#include<map>
#include<set>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<sstream>
#define LL long long
#define OJ_DEBUG 0
#define READ_FILE 0
using namespace std;
const int NN_MAX = 1010;
const int MM_MAX = NN_MAX*NN_MAX;
const int INF = 0x0fffffff;
/**********************************************************/
int n,m,s,t;
int maps[NN_MAX][NN_MAX][2],d[NN_MAX],cost[NN_MAX];
bool vis[NN_MAX];
/**********************************************************/
int min_2 (int x,int y) {return x<y?x:y;}
int max_2 (int x,int y) {return x>y?x:y;}
void dijkstra1();
/**********************************************************/
int main()
{
if (READ_FILE) freopen ("in.txt","r",stdin);
while( scanf("%d %d",&n,&m) && (n||m) )
{
int a1,a2,a3,a4;
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
maps[i][j][0]=maps[i][j][1]=(i==j?0:INF);
for(int i=0;i<m;i++){
scanf("%d %d %d %d",&a1,&a2,&a3,&a4);
if(a3<maps[a1][a2][0]){
maps[a1][a2][0]=a3; maps[a2][a1][0]=a3;
maps[a1][a2][1]=a4; maps[a2][a1][1]=a4;
}
else if(a3==maps[a1][a2][0] && a4<maps[a1][a2][1]){
maps[a1][a2][1]=a4; maps[a2][a1][1]=a4;
}
}
scanf("%d %d",&s,&t);
dijkstra1();
printf("%d %d\n",d[t],cost[t]);
}
return 0;
}
void dijkstra1()
{
for(int i=0;i<=n;i++) cost[i]=INF; cost[s]=0;
for(int i=0;i<=n;i++) d[i]=INF; d[s]=0;
memset(vis,0,sizeof(vis));
for(int k=0;k<n;k++){
int x=0;
for(int i=1;i<=n;i++)
if(!vis[i] && d[i]<d[x]) x=i;
vis[x]=1;
for(int i=1;i<=n;i++)
if(!vis[i] && (d[i]>d[x]+maps[x][i][0]||(d[i]==d[x]+maps[x][i][0]&&cost[i]>cost[x]+maps[x][i][1]) )){
d[i]=d[x]+maps[x][i][0];
cost[i]=cost[x]+maps[x][i][1];
}
}
}
采用优先队列priority_queue和邻接表的dijkstra算法
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<string>
#include<map>
#include<set>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<sstream>
#define LL long long
#define OJ_DEBUG 0
#define READ_FILE 1
using namespace std;
const int NN_MAX = 1010;
const int MM_MAX = NN_MAX*NN_MAX;
const int INF = 0x0fffffff;
struct Node{
int id,dist,weigth;
Node(int a1=0,int a2=0,int a3=0):id(a1),dist(a2),weigth(a3){};
bool operator < (const Node& cst) const{
if(dist>cst.dist) return true;
else if(dist==cst.dist && weigth>cst.weigth) return true;
return false;
}
};
/**********************************************************/
int n,m,s,t;
int d[NN_MAX],cost[NN_MAX];
bool vis[NN_MAX];
vector<Node>G[NN_MAX];
/**********************************************************/
int min_2 (int x,int y) {return x<y?x:y;}
int max_2 (int x,int y) {return x>y?x:y;}
void dijkstra2();
/**********************************************************/
int main()
{
if (READ_FILE) freopen ("in.txt","r",stdin);
while( scanf("%d %d",&n,&m) && (n||m) )
{
int a1,a2,a3,a4;
for(int i=0;i<=n;i++) G[i].clear();
for(int i=0;i<m;i++){
scanf("%d %d %d %d",&a1,&a2,&a3,&a4);
G[a1].push_back(Node(a2,a3,a4));
G[a2].push_back(Node(a1,a3,a4));
}
scanf("%d %d",&s,&t);
dijkstra2();
printf("%d %d\n",d[t],cost[t]);
}
return 0;
}
void dijkstra2()
{
for(int i=0;i<=n;i++)
d[i]=cost[i]=(i==s?0:INF);
memset(vis,0,sizeof(vis));
priority_queue<Node>qee;
qee.push(Node(s,d[s],cost[s]));
while(!qee.empty())
{
Node x=qee.top(); qee.pop();
if(vis[x.id]) continue;
vis[x.id]=1;
for(int i=0;i<G[x.id].size();i++){
Node& y=G[x.id][i];
if(!vis[y.id] && ( d[y.id]>d[x.id]+y.dist ||
(d[y.id]==d[x.id]+y.dist && cost[y.id]>cost[x.id]+y.weigth) ) )
{
d[y.id]=d[x.id]+y.dist;
cost[y.id]=cost[x.id]+y.weigth;
qee.push(Node(y.id,d[y.id],cost[y.id]));
}
}
}
}