题意:n个点m条边无向图,求s到t的最少时间,某些地方需要特定的手拿蛋糕,L表示该点必须左手拿,R同理,M没有要求。
解法:dis[i][j] j表示左手或右手到达i点的最少时间。
#include <bits/stdc++.h>
typedef long long ll ;
#define int ll
int quickpow(int a , int b , int mo){int ans = 1 ;while(b){ if(b&1){ans = ans * a % mo ;}b >>= 1 ;a = a * a % mo ;}return ans ;}
using namespace std ;
#define INF 0x3f3f3f3f
const double PI = acos(-1.0);
const int maxn = 1e5+9;
const int mod = 1e9+7;
int n , m , b , e , t ;
char s[maxn];
int dis[maxn][3] ;//0表示从左手过来的,1表示从右手过来的
bool vis[maxn][3];
vector<pair<int,int>>g[maxn];
struct node{
int u , w , k ;
bool operator < (const node e) const{
return w > e.w;
}
node(int _u , int _w , int _k){
u = _u , w = _w , k = _k;
}
};
int turn(char c){
if(c == 'L') return 0 ;
if(c == 'R') return 1 ;
return 2 ;
}
void dijkstra(int u){
for(int i = 1 ; i <= n ; i++){
dis[i][0] = dis[i][1] = 1e18 ;
vis[i][0] = vis[i][1] = false;
}
priority_queue<node>q;
if(s[u] == 'M'){
dis[u][0] = 0 ;
dis[u][1] = 0 ;
q.push(node(u , dis[u][0] , 0));
q.push(node(u , dis[u][1] , 1));
}else if(s[u] == 'L'){
dis[u][0] = 0 ;
q.push(node(u , dis[u][0] , 0));
}else{
dis[u][1] = 0 ;
q.push(node(u , dis[u][1] , 1));
}
while(!q.empty()){
node now = q.top() ; q.pop();
int u = now.u , nk = now.k;
vis[u][nk] = 1 ;
for(auto j : g[u]){
int v = j.first , w = j.second ;int k = turn(s[v]);
if(vis[v][k])continue;
if((nk == k || k == 2) && dis[v][nk] > dis[u][nk] + w){
dis[v][nk] = dis[u][nk] + w ;
q.push(node(v , dis[v][nk] , nk));
}else if(nk != k && dis[v][k] > dis[u][nk] + w + t){
dis[v][k] = dis[u][nk] + w + t ;
q.push(node(v , dis[v][k] , k));
}
}
}
}
void init(){
for(int i = 1 ; i <= n ; i++){
g[i].clear();
}
}
void Solve(){
cin >> n >> m >> b >> e >> t >> s+1 ;
init();
for(int i = 1 ; i <= m ; i++){
int u , v , w ;
cin >> u >> v >> w ;
g[u].push_back({v , w});
g[v].push_back({u , w});
}
dijkstra(b);
cout << min(dis[e][0] , dis[e][1]) << endl;
}
signed main(){
#ifdef ONLINE_JUDGE
#else
freopen("D:\c++\in.txt", "r", stdin);
freopen("D:\c++\out.txt", "w", stdout);
#endif
int t ;
cin >> t ;
while(t--)
Solve();
}