hdu6805 Deliver the Cake(拆點,dijsktra)
阿新 • • 發佈:2020-08-01
Deliver the Cake
Time Limit: 4000/2000 MS (Java/Others)Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1766Accepted Submission(s): 442
There arenvillages, labeled1,2,…,n. There arem
The bakery locates at villagesand Zhang3's home locates at villaget. So Zhang3 wants to carry the cake fromstot. 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 extrax
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, ifsortis 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).Ttest cases follow.
For each test case, the first line contains five integersn,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 lengthn, describing the type of each village. Theithcharacter is eitherLrepresenting villageiis LEFT, orMrepresenting MIDDLE, orRrepresenting RIGHT.
Finally,mlines follow, theithof which contains three integersai,bi,di(1≤di≤109), denoting a road connecting villageaiandbiof lengthdi.
It is guaranteed thattcan be reached froms.
The sum ofnin all test cases doesn't exceed2×105. The sum ofmdoesn't exceed4×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 Source 2020 Multi-University Training Contest 4 思路: 將必須左手的村莊拆成兩個左手,右手拆成兩個右手,M的村莊拆成一左一右,然後跑dijsktra,然後因為是雙向邊,拆點後點數量變為原來2倍,連邊情況變為原來的4倍,所以存邊的陣列要開8倍;
#include<bits/stdc++.h> using namespace std; #define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0) #define multiCase int TT;cin>>TT;for(int tt=1;tt<=TT;tt++) #define rep(i,a,b) for(int i=a;i<=b;i++) #define repp(i,a,b) for(int i=a;i<b;i++) #define per(i,a,b) for(int i=a;i>=b;i--) #define perr(i,a,b) for(int i=a;i>b;i--) #define pb push_back #define eb push_back #define mst(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> P; const int INF=0x3f3f3f3f; const ll LINF=0x3f3f3f3f3f3f3f3f; const double eps=1e-12; const double PI=acos(-1.0); const double angcst=PI/180.0; const ll mod=998244353; ll max_3(ll a,ll b,ll c){if(a>b&&a>c)return a;if(b>c)return b;return c;} ll min_3(ll a,ll b,ll c){if(a<b&&a<c)return a;if(b<c)return b;return c;} ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} ll qpow(ll a,ll n){ll r=1;while(n){if(n&1)r=(r*a)%mod;n>>=1;a=(a*a)%mod;}return r;} ll qmul(ll a,ll b){ll s=(long double)a/mod*b;s=a*b-s*mod;if(s<0)s+=mod;if(s>=mod)s-=mod;return s;} const int maxn=200010; char ss[maxn],sss[maxn]; int n,m,s,t,x; ll dis[maxn]; int head[maxn],tot; struct node { int u,v,nxt; ll w; }e[8*maxn]; struct qnode { int v; ll dis; bool operator < (const qnode &r)const { return dis>r.dis; } }; void add(int u,int v,ll w) { e[tot].u=u; e[tot].v=v; e[tot].w=w; e[tot].nxt=head[u]; head[u]=tot++; e[tot].u=v; e[tot].v=u; e[tot].w=w; e[tot].nxt=head[v]; head[v]=tot++; } void init() { rep(i,1,2*n)head[i]=-1; tot=0; } ll dij(int s) { rep(i,1,2*n)dis[i]=LINF; priority_queue<qnode>q; dis[s]=0; q.push({s,0}); qnode tmp; while(!q.empty()) { tmp=q.top(); q.pop(); int u=tmp.v; if(tmp.dis>dis[u])continue; for(int i=head[u];i!=-1;i=e[i].nxt) { int v=e[i].v; ll w=e[i].w; ll z=(sss[u]==sss[v]?0:x); if(dis[u]+w+z<dis[v]) { dis[v]=dis[u]+w+z; q.push({v,dis[v]}); } } } return min(dis[t],dis[t+n]); } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d%d%d%d",&n,&m,&s,&t,&x); init(); scanf("%s",ss); rep(i,1,n) { if(ss[i-1]=='M')sss[i]='L',sss[i+n]='R'; else if(ss[i-1]=='L')sss[i]=sss[i+n]='L'; else sss[i]=sss[i+n]='R'; } while(m--) { int u,v; ll w; scanf("%d%d%lld",&u,&v,&w); add(u,v,w);add(u+n,v,w); add(u+n,v+n,w);add(u,v+n,w); } printf("%lld\n",min(dij(s),dij(s+n))); } return 0; }