/* Shortest Path Vairant * Don't be scared!!! * Greedy strategy is still applied. * Just do it! */ #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int g[305][305],it[305],bt[305],pt[305],d[305],p[305]; int src,dst,n,m; bool used[305]; char ic[305]; void Current(int nowT, int at, char &fromC, int &remC) { if(nowT<it[at]) { fromC=ic[at]; remC=it[at]-nowT; } else { nowT-=it[at]; nowT%=(bt[at]+pt[at]); if(ic[at]=='P') { //Careful! if(nowT<bt[at]) { fromC='B'; remC=bt[at]-nowT; } else { fromC='P'; remC=pt[at]-(nowT-bt[at]); } } else { if(nowT<pt[at]) { fromC='P'; remC=pt[at]-nowT; } else { fromC='B'; remC=bt[at]-(nowT-pt[at]); } } } } int calWait(int nowT, int from, int to) { char fromC,toC; int fromR,toR,nextFT,nextTT,nnextFT,nnextTT; //printf("!!%d %d %d = %d\n",nowT,from,to); Current(nowT,from,fromC,fromR); //printf("--CurrentF %d %d %c %d\n",nowT,from,fromC,fromR); Current(nowT,to,toC,toR); //printf("--CurrentT %d %d %c %d\n",nowT,to,toC,toR); //printf("--%d %d %d %d\n",fromC, toC, fromR, toR); if(fromC==toC) return 0; else { if(fromR<toR) return fromR; else if(fromR>toR) return toR; else { if(fromC=='B') nextFT=pt[from]; else nextFT=bt[from]; if(fromC=='B') nnextFT=bt[from]; else nnextFT=pt[from]; if(toC=='B') nextTT=pt[to]; else nextTT=bt[to]; if(toC=='B') nnextTT=bt[to]; else nnextTT=pt[to]; if(nextTT+nnextTT==nextFT+nnextFT) return -1; if(nextTT==nextFT) return fromR+nextFT+min(nnextFT,nnextTT); else return fromR+min(nextFT,nextTT); } } } void print(int x) { if(p[x]!=x) print(p[x]); printf("%d ",x); } int main() { char str[100]; int u,v,w; scanf("%d %d",&src,&dst); scanf("%d %d",&n,&m); gets(str); for(int i=1;i<=n;i++) { scanf("%s %d %d %d",str,&it[i],&bt[i],&pt[i]); ic[i]=str[0]; } for(int i=1;i<=m;i++) { scanf("%d %d %d",&u,&v,&w); g[u][v]=g[v][u]=w; } memset(used,0,sizeof(used)); for(int i=1;i<=n;i++) d[i]=1<<29; d[src]=0; p[src]=src; for(int cc=1;cc<n;cc++) { int md=1<<29,mp=0; for(int i=1;i<=n;i++) if(!used[i]&&d[i]<md) { md=d[i]; mp=i; } if(!mp) break; else used[mp]=true; for(int i=1;i<=n;i++) if(!used[i]&&g[mp][i]) { int wait=calWait(d[mp],mp,i); //printf("wait=%d\n",wait); if(wait<0) continue; if(d[i]>wait+d[mp]+g[mp][i]) { d[i]=wait+d[mp]+g[mp][i]; p[i]=mp; } } } //for(int i=1;i<=n;i++) printf("%d ",d[i]); printf("\n"); if(d[dst]<(1<<29)) printf("%d\n",d[dst]); print(dst); return 0; } |