1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| # include<bits/stdc++.h>
using namespace std;
typedef unsigned int UI; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> pii; typedef pair<LL, LL> pll;
# define mp make_pair # define pb push_back # define lb lower_bound # define ub upper_bound # define fir first # define sec second
# define fo0(i,a,b) for(int i=(a);i<(b);i++) # define fo1(i,a,b) for(int i=(a);i<=(b);i++) # define fd0(i,a,b) for(int i=(a)-1;i>=(b);i--) # define fd1(i,a,b) for(int i=(a);i>=(b);i--) # define mset(a,b) memset(a,(b),sizeof(a)) # define mcpy(a,b) memcpy(a,b,sizeof(a))
template<typename T> inline void in(T &x){x=0;int fl=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-')fl=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}x*=fl;} template<typename T> void out(T x){if(x<0){putchar('-');x=-x;}if(x/10)out(x/10);putchar(x%10+'0');} template<typename T> inline void outln(T x){out(x);putchar(10);} template<typename T> inline void outsp(T x){out(x);putchar(' ');} template<typename T> inline T gcd(T a, T b){T t;if(a>b){while(b){ t=b;b=a%b;a=t;}return a;}else{while(a){t=a;a=b%a;b=t;}return b;}} template<typename T> inline T lcm(T a, T b){return a/gcd(a,b)*b;}
const int N = 155;
int n, m, d, u, v, w, p;
struct Edge{ int nxt, from, to, v, len; }edge[N*N]; int head[N], edgeNum; void addEdge(int from, int to, int v, int len){ edge[++edgeNum] = (Edge){head[from], from, to, v, len}; head[from] = edgeNum; }
double tim[N][505]; bool inq[N][505]; map<pii, pii> pre; void spfa(){ queue<pii> q; q.push({1, 70}); inq[1][70] = 1; tim[1][70] = 0; pre[{1, 70}] = {0, 0}; while(!q.empty()){ pii cur = q.front(); q.pop(); inq[cur.fir][cur.sec] = 0; int x = cur.fir, sp = cur.sec; for(int i = head[x]; i; i = edge[i].nxt){ if(edge[i].v == 0){ if(tim[edge[i].to][sp] > tim[x][sp] + (double)edge[i].len / sp){ tim[edge[i].to][sp] = tim[x][sp] + (double)edge[i].len / sp; pre[{edge[i].to, sp}] = {x, sp}; if(!inq[edge[i].to][sp]){ q.push({edge[i].to, sp}); inq[edge[i].to][sp] = 1; } } } else{ if(tim[edge[i].to][edge[i].v] > tim[x][sp] + (double)edge[i].len / edge[i].v){ tim[edge[i].to][edge[i].v] = tim[x][sp] + (double)edge[i].len / edge[i].v; pre[{edge[i].to, edge[i].v}] = {x, sp}; if(!inq[edge[i].to][edge[i].v]){ q.push({edge[i].to, edge[i].v}); inq[edge[i].to][edge[i].v] = 1; } } } } } }
int main(){ in(n); in(m); in(d); d++; fo1(i, 1, m){ in(u); in(v); in(w); in(p); addEdge(u+1, v+1, w, p); } fo1(i, 1, n) fo1(j, 1, 500) tim[i][j] = 1e9; spfa(); double ans = 1e9; pii mark; fo1(i, 1, 500){ if(ans > tim[d][i]){ ans = tim[d][i]; mark = {d, i}; } } stack<int> sta; while(mark.fir){ sta.push(mark.fir); mark = pre[mark]; } while(!sta.empty()){ outsp(sta.top()-1); sta.pop(); } return 0; }
|