Problem Description
It is Zhang3’s birthday! Zhang3 has bought a birthday cake and now it’s time to take it home.
There are n villages, labeled 1,2,…,n. There are m bidirectional roads, the ith of which connects village ai, bi and it is di meter(s) long.
The bakery locates at village s and Zhang3’s home locates at village t. So Zhang3 wants to carry the cake from s to t. She can carry the cake either with her left hand or with her right hand. She can switch to the other hand during the trip, which takes extra x second(s) each time (when she’s performing this action, she must stay in her place). Switching is allowed at any place, including the middle of the roads. She can do this as many times as she like, or don’t do it at all.
Some villages are LEFT. When Zhang3 is at a LEFT village, she must carry the cake with her left hand at the moment. In the same way, some other villages are RIGHT, she must carry with her right hand when she’s at these villages. The rest villages are called MIDDLE. There’s no special rules at MIDDLE villages.
Zhang3 can start and finish with any hand carrying the cake. However, if s or t is not MIDDLE, their special rules must be followed.
Please help Zhang3 find a way to take the cake home, with the minimum amount of spent time.
Input
The first line of the input gives the number of test cases, T(1≤T≤100). T test cases follow.
For each test case, the first line contains five integers n,m,s,t,x(1≤n≤105,1≤m≤2×105,1≤x≤109), representing the number of villages, the number of roads, the bakery’s location, home’s location, and the time spent for each switching.
The next line contains a string of length n, describing the type of each village. The ith character is either L representing village i is LEFT, or M representing MIDDLE, or R representing RIGHT.
Finally, m lines follow, the ith of which contains three integers ai,bi,di(1≤di≤109), denoting a road connecting village ai and bi of length di.
It is guaranteed that t can be reached from s.
The sum of n in all test cases doesn’t exceed 2×105. The sum of m doesn’t exceed 4×105.
Output
For each test case, print a line with an integer, representing the minimum amount of spent time (in seconds).
题意:
n个村庄,m条边,边的权值为w,村庄种类分为L,R,M三种, M兼容R和L,改变状态需要额外加上时间x,问从点s到点t的最少时间。
杭电多校的题目,刚开始把题目想的过于简单,直接上了一个最裸的dij模板,结果wa到自闭,比赛结束后发现它过不了下面这组数据,
1
5 5 1 5 1000
RLRMR
1 2 1
1 3 1100
2 4 1
3 4 10
4 5 1
正确答案是1111,正确的最短路是1->3->4->5,但是一层的dij只会跑成1->2->4->5.所以我在原基础上加了一层图,dis[i][0]储存上一个点是L的状态,dis[i][1]储存上一个点是R的状态,最后输出取个小值。
#include<bits/stdc++.h>
using namespace std;
#define PI acos(-1)
#define INF 0x3f3f3f
#define ll long long
#define pb push_back
#define mp make_pair
#define pair pair<int,int>
#define C(a) cout<<a<<endl;
#define CY cout<<"YES"<<endl;
#define CN cout<<"NO"<<endl;
#define Cy cout<<"Yes"<<endl;
#define Cn cout<<"No"<<endl;
#define ull unsigned long long
#define me(a) memset(a,0,sizeof(a));
#define my(a,b) memcpy(a,b,sizeof(b));
#define cio ios::sync_with_stdio(false)
ll mod=1e9+7;
ll gcd(ll a,ll b){return (a%b==0) ? b : gcd(b,a%b);}
ll cnt=1,vis[100010][2],dis[100010][2],head[100010];
ll n;
ll xx;
char s[100010];
struct edge{
ll to;
ll next;
ll w;
}edges[10000010];
struct node{
ll x;
ll w;
char a;
inline bool operator <(const node &x)const
{
return w>x.w;
}
};
inline void add(ll u,ll v,ll w){
edges[cnt].to=v;
edges[cnt].next=head[u];
edges[cnt].w=w;
head[u]=cnt++;
}
void dij(ll ss,char a){
priority_queue<node>que;
memset(dis,-1,sizeof(dis));
if(a!='L'){
que.push((node){ss,0,'R'});
dis[ss][0]=0;
}
if(a!='R'){
que.push((node){ss,0,'L'});
dis[ss][1]=0;
}
me(vis);
while(!que.empty())
{
node p=que.top();
que.pop();
if(p.a=='L')
{
if(vis[p.x][0]) continue;
vis[p.x][0]=1;
for(int i=head[p.x];i;i=edges[i].next){
ll x=edges[i].to;
ll w=edges[i].w;
if(p.a!=s[x]&&s[x]!='M'){
w+=xx;
}
if(dis[x][0]==-1||dis[x][0]>p.w+w)
{
dis[x][0]=p.w+w;
if(s[x]!='M')
que.push((node){x,dis[x][0],s[x]});
else{
que.push((node){x,dis[x][0],p.a});
}
}
}
}else{
if(vis[p.x][1]) continue;
vis[p.x][1]=1;
for(int i=head[p.x];i;i=edges[i].next){
ll x=edges[i].to;
ll w=edges[i].w;
if(p.a!=s[x]&&s[x]!='M'){
w+=xx;
}
if(dis[x][1]==-1||dis[x][1]>p.w+w)
{
dis[x][1]=p.w+w;
if(s[x]!='M')
que.push((node){x,dis[x][1],s[x]});
else{
que.push((node){x,dis[x][1],p.a});
}
}
}
}
}
}
int main(){
int tt;
scanf("%d",&tt);
while(tt--){
cnt=1;
me(head);
ll m,s1,t,u,v;
ll w;
scanf("%lld %lld %lld %lld %lld",&n,&m,&s1,&t,&xx);
scanf("%s",s+1);
for(int i=0;i<m;i++)
{
scanf("%lld %lld %lld",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
ll min1;
dij(s1,s[s1]);
if(dis[t][0]!=-1&&dis[t][1]!=-1){
min1=min(dis[t][0],dis[t][1]);
}else{
min1=dis[t][0]==-1?dis[t][1]:dis[t][0];
}
printf("%lld\n",min1);
}
return 0;
}