1. 程式人生 > 實用技巧 >hdu6805 Deliver the Cake(拆點,dijsktra)

hdu6805 Deliver the Cake(拆點,dijsktra)

Deliver the Cake

Time Limit: 4000/2000 MS (Java/Others)Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1766Accepted Submission(s): 442


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

There arenvillages, labeled1,2,,n. There arem
bidirectional roads, theithof which connects villageai,biand it isdimeter(s) long.

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
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, 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(1T100).Ttest cases follow.

For each test case, the first line contains five integersn,m,s,t,x(1n105,1m2×105,1x109), 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(1di109), 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;
}