给一个无向图,n个点,m条边条边。
每个点有一个属性:LRM。
到哪个点需要和他属性保持一致,M是任意属性。
L与R相互转换需要消耗时间x。求最短路。
比传统的最短路来说,多了些变化。我们可以把需要L与R转换的边权值加个x.
由于存在M的点可以是L或R,我们将其拆分成两个点值分别是L和R就行。
注意当起点或是终点是M时,会有两个起点或终点。我们在外面建一个源点就行了。
#include
#define ll long long
#define p pair
using namespace std;
const int N=2e6+10;
int h[N],to[N],ne[N],cnt,vis[N];
ll cost[N],w,dis[N];
int n,m,s,t,x;
int u,v;
char str[N];
inline ll rd()
{
register ll s=0,w=1;
register char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
void add(int u,int v,int w){
cost[cnt]=w,to[cnt]=v,ne[cnt]=h[u],h[u]=cnt++;
}
ll dij(){
memset(dis,1e9+7,sizeof(dis));
if(str[s]=='M') dis[0]=0;
else dis[s]=0;
priority_queue,greater
>q;
if(str[s]=='M') q.push({0,0});
else q.push({0,s});
while(!q.empty()){
p id=q.top();
q.pop();
int u=id.second;
vis[u]=1;
for(int i=h[u];~i;i=ne[i]){
int k=to[i];
//printf("u=%d,k=%d,r=%d,hand=%c\n",u,k,r,hand);
if(dis[k]>dis[u]+cost[i])
{
dis[k]=dis[u]+cost[i];
q.push({dis[k],k});
}
}
}
if(str[t]= ='M')return dis[2*n+1];
else return dis[t];
}
int main(){
int o;
o=rd();
while(o--){
memset(h,-1,sizeof(h));
memset(vis,0,sizeof(vis));
cnt=0;
n=rd(),m=rd(),s=rd(),t=rd(),x=rd();
for(int i=1;i<=n;i++)
scanf("%c",&str[i]);
if(str[s]= ='M')
{
add(0,s,0), add(s,0,0);
add(0,s+n,0), add(s+n,0,0);
}
if(str[t]= ='M')
{
add(2*n+1,t,0), add(t,2*n+1,0);
add(2*n+1,t+n,0), add(t+n,2*n+1,0);
}
for(int i=1;i<=m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if((str[a]= ='L'&&str[b]= ='R') || (str[a]= ='R'&&str[b]= ='L'))
{
add(a,b,c+x), add(b,a,c+x); //LR or RL
}
else if((str[a]=='L'&&str[b]=='L') || (str[a]=='R'&&str[b]=='R'))
{
add(a,b,c), add(b,a,c); //LL or RR
}
else if(str[a]=='L'&&str[b]=='M')
{
add(a,b,c), add(b,a,c); // LL
add(a,n+b,c+x), add(n+b,a,c+x); //LR
}
else if(str[a]=='M'&&str[b]=='L')
{
add(a,b,c), add(b,a,c); //LL
add(a+n,b,c+x), add(b,a+n,c+x); //RL
}
else if(str[a]=='R'&&str[b]=='M')
{
add(a,b,c+x), add(b,a,c+x); //RL
add(a,n+b,c), add(n+b,a,c); //RR
}
else if(str[a]=='M'&&str[b]=='R')
{
add(a,b,c+x), add(b,a,c+x); //LR
add(a+n,b,c), add(b,a+n,c); //RR
}
else if(str[a]=='M'&&str[b]=='M')
{
add(a,b,c), add(b,a,c); //LL
add(a,b+n,c+x), add(b+n,a,c+x); //LR
add(a+n,b,c+x), add(b,a+n,c+x); //RL
add(a+n,b+n,c), add(b+n,a+n,c); //RR
}
}
printf("%lld\n",dij());
}
return 0;
}