easy
http://www.patest.cn/contests/pat-a-practise/1030
这次比较简单,直接用dij同时更新cost和dis,即可得到答案
#include <cstdio>
#include <string.h>
#include <vector>
using namespace std;
#define MAX 510
//g图存放距离,其本身有2层含义,一是非-1表示两点的距离,即两点联通,
//二是-1表示两点不连通
int g[MAX][MAX];
int c[MAX][MAX];
int dis[MAX];
int cost[MAX];
int vis[MAX];
int n,m,s,d;
int pre[MAX];
void dij(int &gg,int &cc){
for(int i=0;i<n;i++){
pre[i]=i;
}
int newp=s;
vis[newp]=1;
dis[newp]=0;
cost[newp]=0;
for(int i=0;i<n-1;i++){
for(int j=0;j<n;j++){
if(g[newp][j]!=-1 && vis[j]==0){
if(dis[j]==-1 || dis[j]>dis[newp]+g[newp][j]){
dis[j]=dis[newp]+g[newp][j];
cost[j]=cost[newp]+c[newp][j];
pre[j]=newp;
}else if(dis[j]==dis[newp]+g[newp][j] && cost[j]==-1 || cost[j]>cost[newp]+c[newp][j]){
cost[j]=cost[newp]+c[newp][j];
pre[j]=newp;
}
}
//由于为无向图,因此邻接矩阵对称,只需要考虑一方面即可
/*if(g[j][newp]!=-1){
if(vis[j]==0 ){
if(dis[j]==-1 || dis[j]>dis[newp]+g[j][newp]){
dis[j]=dis[newp]+g[j][newp];
cost[j]=cost[newp]+c[j][newp];
pre[j]=newp;
}else if(dis[j]==dis[newp]+g[j][newp] && cost[j]==-1 || cost[j]>cost[newp]+c[j][newp]){
cost[j]=cost[newp]+c[j][newp];
pre[j]=newp;
}
}
}*/
}
int mind=123123123;
int minc=123123123;
for(int j=0;j<n;j++){
if(vis[j]==0 && dis[j]!=-1){
if(dis[j]<mind){
mind=dis[j];
newp=j;
}else if(dis[j]==mind && cost[j]<minc){
mind=dis[j];
minc=cost[j];
newp=j;
}
}
}
vis[newp]=1;
}
}
int main(){
freopen("in.txt","r",stdin);
memset(g,-1,sizeof(g));
memset(c,-1,sizeof(c));
memset(dis,-1,sizeof(dis));
memset(cost,-1,sizeof(cost));
memset(vis,0,sizeof(vis));
scanf("%d %d %d %d",&n,&m,&s,&d);
for(int i=0;i<m;i++){
int a,b,gg,cc;
scanf("%d %d %d %d",&a,&b,&gg,&cc);
g[a][b]=gg;
g[b][a]=gg;
c[a][b]=cc;
c[b][a]=cc;
}
int gg=123123123;
int cc=123123123;
dij(gg,cc);
int path[MAX];
int k=0;
int p=d;
while(pre[p]!=p){
path[k++]=p;
p=pre[p];
}
path[k++]=p;
for(int i=k-1;i>=0;i--){
printf("%d ",path[i]);
}
printf("%d %d\n",dis[d],cost[d]);
return 0;
}