hdu 2020多校 round4 Deliver the Cake

题意

给一个无向图,n个点,m条边条边。
每个点有一个属性:LRM。
到哪个点需要和他属性保持一致,M是任意属性。
L与R相互转换需要消耗时间x。求最短路。
比传统的最短路来说,多了些变化。我们可以把需要L与R转换的边权值加个x.
由于存在M的点可以是L或R,我们将其拆分成两个点值分别是L和R就行。
注意当起点或是终点是M时,会有两个起点或终点。我们在外面建一个源点就行了。

代码:

#include<bits/stdc++.h>
#define ll long long
#define p pair<ll,int>
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<p,vector<p>,greater<p> >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;
}

猜你喜欢

转载自blog.csdn.net/Nefeertari/article/details/107711276