现在给你一个城市网络,求从某点到某点的最短路。每个点上都有一个红绿灯,仅有红绿两种颜色,按照某个周期切换,尽在边的两个端点的灯同色时,这条边才可走。
直接用最短路算法即可,走某条路径之前要加上的等待灯的时间。注意如果两个灯交替变换,那这条路时永远不能走的。
#include <cstdio>
#include <queue>
using namespace std;
int min(int a,int b) {
return a<b?a:b;
}
struct Node {
int fe,v,from;
int c,r,t[2];
void read() {
fe=v=from=-1;
char cc;
scanf(" %c",&cc);
if (cc=='B') c=0;
else c=1;
scanf("%d%d%d",&r,&t[0],&t[1]);
}
};
struct Edge {
int t,ne,v;
};
struct QueNode {
int i,v;
QueNode() {}
QueNode(int ii,int vv) {
i=ii;v=vv;
}
friend bool operator < (const QueNode &a,const QueNode &b) {
return a.v>b.v;
}
};
Node a[301];
Edge b[28000];
priority_queue<QueNode> c;
int s,t,n,m,p;
void putedge(int x,int y,int z) {
b[p].t=y;
b[p].v=z;
b[p].ne=a[x].fe;
a[x].fe=p++;
}
void cal(int &it,int &ic,int i,int t) {
t%=(a[i].t[0]+a[i].t[1]);
ic=a[i].c;
if (t<a[i].r) it=a[i].r-t;
else {
t-=a[i].r;
ic^=1;
if (t<a[i].t[ic]) it=a[i].t[ic]-t;
else {
t-=a[i].t[ic];
ic^=1;
it=a[i].t[ic]-t;
}
}
}
int wait(int i,int j,int t) {
int it,ic,jt,jc;
cal(it,ic,i,t);
cal(jt,jc,j,t);
//printf("%d %d %d %d\n",it,ic,jt,jc);
if (ic==jc) return 0;
if (it!=jt) return min(it,jt);
if (a[i].t[jc]!=a[j].t[ic]) return jt+min(a[i].t[jc],a[j].t[ic]);
if (a[i].t[ic]!=a[j].t[jc]) return jt+a[j].t[ic]+min(a[i].t[ic],a[j].t[jc]);
return -1;
}
void dij(int s,int t) {
int i,j;
a[s].v=0;
c.push(QueNode(s,0));
while (!c.empty()) {
i=c.top().i;
if (i==t) return;
if (c.top().v==a[i].v) {
for (j=a[i].fe;j!=-1;j=b[j].ne) {
int tmp=wait(i,b[j].t,a[i].v);
//printf("--%d %d %d %d\n",i,b[j].t,a[i].v,tmp);
if (tmp!=-1) {
tmp+=a[i].v+b[j].v;
if (a[b[j].t].v==-1||tmp<a[b[j].t].v) {
a[b[j].t].from=i;
a[b[j].t].v=tmp;
c.push(QueNode(b[j].t,tmp));
}
}
}
}
c.pop();
}
}
int main() {
int i,x,y,z;
int ans[300];
scanf("%d%d",&s,&t);
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++) {
a[i].read();
}
p=0;
for (i=0;i<m;i++) {
scanf("%d%d%d",&x,&y,&z);
putedge(x,y,z);
putedge(y,x,z);
}
dij(s,t);
if (a[t].v==-1) printf("0\n");
else {
printf("%d\n",a[t].v);
p=0;
for (i=t;i!=-1;i=a[i].from) ans[p++]=i;
while (p) printf("%d ",ans[--p]);
printf("\n");
}
return 0;
}