http://acm.sgu.ru/problem.php?contest=0&problem=103
有条件限制的最短路问题,当且仅当点的颜色一样时可以通行否则需要等到符合条件时才可以通行。等待的时间与通行时间之和用于判断松弛。
AC代码:
#include <queue>
#include <stack>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXV = 310;
const int MAXE = 14010;
const int INF = 0x3f3f3f3f;
typedef pair <int, int> Pii;
vector <Pii> vt[MAXV];
struct NODE{
int c, rt, bt, pt;
int color(int t){
if(t < rt) return c;
t -= rt;
t %= (bt + pt);
if(c == 1){
if(t < bt) return c^1;
return c;
}
if(t < pt) return c^1;
return c;
}
}node[MAXV];
queue <int> Q;
int dis[MAXV],vis[MAXV],pre[MAXV];
void SPFA(int st){
memset(dis, 0x3f, sizeof(dis));
memset(vis, 0, sizeof(vis));
memset(pre, -1, sizeof(pre));
dis[st] = 0, vis[st] = 1;
Q.push(st);
while(!Q.empty()){
int u = Q.front();
Q.pop();
vis[u] = 0;
int t = dis[u];
for(int i=0; i<vt[u].size(); i++){
int v = vt[u][i].first;
int w = vt[u][i].second;
int T = t;
while(t + 100 >= T && node[u].color(T) != node[v].color(T)) T++;
if(T > t + 100) continue;
if(T + w < dis[v]){
dis[v] = T + w;
pre[v] = u;
if(vis[v]) continue;
Q.push(v);
vis[v] = 1;
}
}
}
}
int main(){
int st,ed,N,M;
scanf("%d%d%d%d",&st,&ed,&N,&M);
for(int i=1; i<=N; i++){
char str[10];
scanf("%s",str);
if(str[0] == 'B') node[i].c = 0;
else node[i].c = 1;
scanf("%d%d%d",&node[i].rt,&node[i].bt,&node[i].pt);
}
for(int i=0; i<M; i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
vt[a].push_back(Pii(b,c));
vt[b].push_back(Pii(a,c));
}
SPFA(st);
if(dis[ed] == 0x3f3f3f3f){
cout << 0 << endl;
return 0;
}
printf("%d\n",dis[ed]);
stack <int> S;
while(ed != -1){
S.push(ed);
ed = pre[ed];
}
printf("%d",S.top()); S.pop();
while(S.size()){
printf(" %d",S.top());
S.pop();
}
printf("\n");
///system("pause");
return 0;
}