Dijkstra+优先队列
//Dijkstra+优先队列
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int MAXV = 510;
const int INF = 0x3fffffff;
//n为顶点, m为边数, st和ed分别为起点和终点
//Adj[MAXV]为邻接表
//d[]记录最短距离
int n, m, st, ed;
int d[MAXV];
int c[MAXV], cost[MAXV][MAXV];
struct Node{ //It's just a node!
int v, dis; //dis:距离起点s的距离;v:点
friend bool operator < (Node a, Node b){
return a.dis>b.dis;
}
};
bool vis[MAXV]={false};
vector<Node> Adj[MAXV]; //邻接链表存储图
priority_queue<Node> Q; //优先队列找出最短的那条边;
int pre[MAXV]; //前驱路径
//S存放已被访问过的顶点, 然后每次从集合V-S中选择与起点s的最短的顶点(记为u),访问并加入集合S
//令u为中介点,优化(更新)起点s与所有从u能到达的顶点v之间的最短距离。
void Dijkstra(int s){
fill(d, d+MAXV, INF);
fill(c, c+MAXV, INF);
for(int i=0;i<n;i++) pre[i]=i;
d[s]=0;
c[s]=0;
while(!Q.empty()) Q.pop();
Node now; //起始点st的初始化
now.v=s;
now.dis=0;
Q.push(now);
while(!Q.empty()){
now=Q.top();
Q.pop();
int u=now.v;
if(vis[u]) continue; //*****
vis[u]=true;
for(int j=0;j<Adj[u].size();j++){
int v=Adj[u][j].v; //与u邻接的点的id
if(vis[v]==false){
if(d[u]+Adj[u][j].dis<d[v]){
d[v]=d[u]+Adj[u][j].dis;
c[v]=c[u]+cost[u][v];
pre[v]=u;
}else if(d[u]+Adj[u][j].dis==d[v] && c[u]+cost[u][v]<c[v]){
c[v]=c[u]+cost[u][v];
pre[v]=u;
}
}
//老是忘记的部分!!!
Node next;
next.dis=d[v];
next.v=v;
Q.push(next);
}
}
}
void DFS(int v){
if(v==st){
printf("%d ", v);
return ;
}
DFS(pre[v]);
printf("%d ", v);
}
int main(){
int i;
scanf("%d%d%d%d", &n, &m, &st, &ed);
int u, v, tmpdis, tmpcost;
for(i=0;i<m;i++){
scanf("%d%d%d%d", &u, &v, &tmpdis, &tmpcost);
Node tmp;
tmp.v=v;
tmp.dis=tmpdis;
Adj[u].push_back(tmp);
cost[u][v]=cost[v][u]=tmpcost;
tmp.v=u;
tmp.dis=tmpdis;
Adj[v].push_back(tmp);
}
Dijkstra(st);
DFS(ed);
printf("%d %d\n", d[ed], c[ed]);
return 0;
}
DFS+Dijkstra
//DFS+Dijkstra
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int maxn=110;
const int MAXV=510;
const int INF=0x3fffffff;
int n, m, st, ed;
int d[MAXV], c[MAXV], cost[MAXV][MAXV], minCost=INF;
int G[MAXV][MAXV]; //邻接矩阵存储图
bool vis[MAXV]={false};
vector<int> pre[MAXV];
vector<int> tempPath, path;
void Dijkstra(int s){
fill(d, d+MAXV, INF);
d[s]=0;
for(int i=0;i<n;i++){ //仅仅是循环n次!!!因为有n个城市(点)
int u=-1,MIN=INF;
for(int j=0;j<n;j++){
if(vis[j]==false && d[j]<MIN){
u=j;
MIN=d[j];
}
}
if(u==-1) return;
vis[u]=true;
for(int v=0;v<n;v++){
if(vis[v]==false && G[u][v]!=INF){
if(d[u]+G[u][v]<d[v]){
d[v]=d[u]+G[u][v];
pre[v].clear();
pre[v].push_back(u);
}else if(d[u]+G[u][v]==d[v]){
pre[v].push_back(u);
}
}
}
}
}
void DFS(int v){
if(v==st){
tempPath.push_back(v);
int tempCost=0;
for(int i=tempPath.size()-1;i>0;i--){
int id=tempPath[i],idNext=tempPath[i-1];
tempCost+=cost[id][idNext];
}
if(tempCost<minCost){
minCost=tempCost;
path=tempPath;
}
tempPath.pop_back();
return;
}
tempPath.push_back(v);
for(int i=0;i<pre[v].size();i++){
DFS(pre[v][i]);
}
tempPath.pop_back();
}
int main(){
int i;
scanf("%d%d%d%d", &n, &m, &st, &ed);
int u, v;
fill(G[0], G[0]+MAXV*MAXV,INF);
fill(cost[0],cost[0]+MAXV*MAXV,INF);
for(i=0;i<m;i++){
scanf("%d%d", &u, &v);
scanf("%d%d", &G[v][u], &cost[v][u]);
G[u][v]=G[v][u];
cost[u][v]=cost[v][u];
}
Dijkstra(st);
DFS(ed);
for(i=path.size()-1;i>=0;i--){
printf("%d ", path[i]);
}
printf("%d %d\n", d[ed], minCost);
return 0;
}