HDU - 6805 D - Deliver the Cake

It is Zhang3's birthday! Zhang3 has bought a birthday cake and now it's time to take it home. 

There are nn villages, labeled 1,2,…,n1,2,…,n. There are mm bidirectional roads, the ithith of which connects village aiai, bibi and it is didi meter(s) long. 

The bakery locates at village ss and Zhang3's home locates at village tt. So Zhang3 wants to carry the cake from ss to tt. 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 xx 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 ss or tt 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(1≤T≤100). TT 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)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 nn, describing the type of each village. The ithith character is either LL representing village ii is LEFT, or MM representing MIDDLE, or RR representing RIGHT. 

Finally, mm lines follow, the ithith of which contains three integers ai,bi,di(1≤di≤109)ai,bi,di(1≤di≤109), denoting a road connecting village aiai and bibi of length didi. 

It is guaranteed that tt can be reached from ss. 

The sum of nn in all test cases doesn't exceed 2×1052×105. The sum of mm doesn't exceed 4×1054×105. 

Output

For each test case, print a line with an integer, representing the minimum amount of spent time (in seconds). 

Sample Input

1
3 3 1 3 100
LRM
1 2 10
2 3 10
1 3 100

Sample Output

100

Sponsor

拆点建图

一开始习惯性敲spfa。。。

然后t了好久

dij秒过 记得开longlong

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 2e6 + 5;
int head[maxn];
int vis[maxn];
ll dis[maxn];
int tot;
int T, S;
int n, m;
ll vl;
char val[maxn];
struct node{
    int to;
    int next;
    ll v;
    node() {}
    node(int a, int b, ll c) : to(a), next(b), v(c) {}
} edge[maxn];
 
void edgeadd(int s, int e, ll v){
    edge[tot] = node(e, head[s], v);
    head[s] = tot++;
    edge[tot] = node(s, head[e], v);
    head[e] = tot++;
}
 
void init(){
    memset(head, -1, sizeof(head));
    tot = 0;
}
 
struct  Node{
    int num;
    ll c;
    Node() {}
    Node(int a, ll b) : num(a), c(b) {}
    bool operator < (const Node &rsh)const{
        return c > rsh.c;
    }
};
 
void dijstra(int str){
	memset(vis, 0, sizeof(vis));
    memset(dis, 0x3f3f3f3f3f3f3f3f, sizeof(dis));
    priority_queue<Node> q;
    while(!q.empty()){
        q.pop();
    }
    q.push(Node(str, 0));
    dis[str] = 0;
    Node p;
    while(!q.empty()){
        p = q.top();
        q.pop();
        int u = p.num;
        if(vis[u]) continue;
        vis[u] = 1;
        for(int i = head[u]; i != -1; i = edge[i].next){
            int v = edge[i].to;
            ll val = edge[i].v;
            if(!vis[v] && dis[v] > dis[u] + val){
                dis[v] = dis[u] + val;
                q.push(Node(v, dis[v]));
            }
        }
    }
}

int main(){
	ios::sync_with_stdio(false);
	int t;
	cin >> t;
	while(t--){
		init();
		cin >> n >> m >> S >> T >> vl;
		for(int i = 1; i <= n; i++)
			cin >> val[i];
		for(int i = 1; i <= m; i++){
			int a, b;
			ll vv;
			cin >> a >> b >> vv;
			if(val[a] != 'M' && val[b] != 'M'){
				if(val[a] == val[b]){
					edgeadd(a, b, vv);
				}
				else{
					edgeadd(a, b, vv + vl);
				}
			}
			else{
				if(val[a] != 'M' && val[b] == 'M'){
					if(val[a] == 'R'){
						edgeadd(a, b, vv);
						edgeadd(a, b + n, vv + vl);
					}
					else{
						edgeadd(a, b + n, vv);
						edgeadd(a, b, vv + vl);
					
					}
				}
				if(val[a] == 'M' && val[b] != 'M'){
					if(val[b] == 'R'){
						edgeadd(a, b, vv);
						edgeadd(a + n, b, vv + vl);
					}
					else{
						edgeadd(a + n, b, vv);
						edgeadd(a, b, vv + vl);
					}
				}
				if(val[a] == 'M' && val[b] == 'M'){
					edgeadd(a, b, vv);
					edgeadd(a + n, b + n, vv);
					edgeadd(a + n, b, vv + vl);
					edgeadd(a, b + n, vv + vl);
				} 
			}
		}
		ll ans;
		if(val[S] == 'M' && val[T] == 'M'){
			dijstra(S);
			ans = min(dis[T], dis[T + n]);
			dijstra(S + n);
			ans = min(ans, min(dis[T], dis[T + n]));
		}
		if(val[S] != 'M' && val[T] == 'M'){
			dijstra(S);
			ans = min(dis[T], dis[T + n]);
		}
		if(val[S] == 'M' && val[T] != 'M'){
			dijstra(S);
			ans = dis[T];
			dijstra(S + n);
			ans = min(ans, dis[T]);
		}
		if(val[S] != 'M' && val[T] != 'M'){
			dijstra(S);
			ans = dis[T];
		}
		cout << ans << endl;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值