#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;
const int maxn = 2010;
const int INF = 0x3ffffff;
int n,m,s,ed;
vector<int>pre[maxn];
bool vist[maxn] = {false};
int d[maxn] ={0};
struct node
{
int cost;
int len;
};
node G[maxn][maxn];
void Dijstra(int start)
{
fill(d,d+n,INF);
d[start] = 0;
for(int i = 0;i<n;i++)
{
int u = -1,MIN = INF;
for(int j = 0;j<n;j++)
{
if(d[j] < MIN && vist[j] == false)
{
MIN = d[u];
u = j;
}
}
if(u == -1 ) return;
vist[u] = true;
for(int j = 0;j<n;j++)
{
if(G[u][j].len > 0 && vist[j] == false)
{
if( d[j] > d[u] + G[u][j].len)
{
d[j] = d[u] + G[u][j].len;
pre[j].clear();
pre[j].push_back(u);
}
else if(d[j] == d[u] + G[u][j].len)
{
pre[j].push_back(u);
}
}
}
}
}
vector<int> path;
vector<int> temppath;
int mincost = 0x3fffff;
void DFS(int st)
{
if(st == s)
{
temppath.push_back(st);
int total = 0;
for(int i = temppath.size()-1;i>0;i--)
{
int id = temppath[i],idn = temppath[i-1];
total += G[id][idn].cost;
}
if(total < mincost)
{
path = temppath;
mincost = total;
}
temppath.pop_back();
return;
}
for(int i = 0;i<pre[st].size();i++)
{
temppath.push_back(st);
int temp = pre[st][i];
DFS(pre[st][i]);
temppath.pop_back();
}
}
void initia()
{
for(int i = 0;i<n;i++)
{
for(int j = 0;j<n;j++)
{
G[i][j].len = 0;
G[j][i].len = 0;
}
}
}
int main()
{
initia();
scanf("%d %d %d %d",&n,&m,&s,&ed);
for(int i=0;i<m;i++)
{
int c1,c2,clen,ccos;
scanf("%d %d %d %d",&c1,&c2,&clen,&ccos);
G[c1][c2].cost = ccos;
G[c1][c2].len = clen;
G[c2][c1].cost = ccos;
G[c2][c1].len = clen;
}
Dijstra(s);
DFS(ed);
int ansc = 0,anclen = 0;
for(int i = 0;i<path.size() - 1;i++)
{
int id1 = path[i],id2 = path[i+1];
ansc += G[id1][id2].cost;
anclen += G[id1][id2].len;
}
for(int i = path.size() - 1;i>=0;i--)
{
printf("%d ",path[i]);
}
printf("%d %d",anclen,ansc);
return 0;
}
#include <cstdio>
#include <vector>
#include<queue>
#include<algorithm>
using namespace std;
const int maxv = 1010,INF = 0x3fffffff;
bool vis[maxv]{false};
int n,m,c1,c2;
int G[maxv][maxv] = {0};
int cost[maxv][maxv] = {0};
int cm[maxv]={0};
//struct node
//{
// int x;
// int dis;
//};
//vector<node>G[maxv];
vector<int>pre[maxv];
int d[maxv];
void Dij(int s)
{
fill(d,d+maxv,INF);
d[s] = 0;
for(int i = 0;i<n;i++)
{
int u = -1,minn = INF;
for(int j = 0;j<n;j++)
{
if(vis[j] == false && d[j] < minn)
{
u = j;
minn = d[j];
}
}
if(u == -1)break;
vis[u] = true;
for(int j = 0;j<n;j++)
{
if(vis[j] == false && G[u][j] != INF)
{
if(d[j] > d[u] + G[u][j])
{
d[j] = d[u] + G[u][j];
pre[j].clear();
pre[j].push_back(u);
}
else if(d[j] == d[u] + G[u][j])
{
pre[j].push_back(u);
}
}
}
}
}
vector<int>tempP,path;
int minn = INF;
void DFS(int s)
{
if(s == c1)
{
tempP.push_back(s);
int value = 0;
for(int i = tempP.size() - 1;i>0;i--)
{
int id = tempP[i],idnext = tempP[i-1];
value += cost[id][idnext];
}
if(value < minn)
{
minn = value;
path = tempP;
}
tempP.pop_back();
return;
}
tempP.push_back(s);
for(int i = 0;i<pre[s].size();i++)
{
DFS(pre[s][i]);
}
tempP.pop_back();
}
int main()
{
freopen("in.txt","r",stdin);
fill(G[0],G[0] + maxv * maxv,INF);
fill(cost[0],cost[0] + maxv * maxv,INF);
scanf("%d%d%d%d",&n,&m,&c1,&c2);
for(int i = 0;i<m;i++)
{
int id1,id2,l,f;
scanf("%d%d%d%d",&id1,&id2,&l,&f);
G[id1][id2] = l;
G[id2][id1] = l;
cost[id1][id2]=f;
cost[id2][id1]=f;
}
Dij(c1);
DFS(c2);
for(int i = path.size() - 1;i>=0;i--)
{
printf("%d ",path[i]);
}
printf("%d %d",d[c2],minn);
}