hdu6805 Deliver The Cake // Dijkstra&拆点

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6805

题目大意 :给定n个点,m条边的图;对于每一个点,其具有L/R/M的属性,表示通过该点时必须选择 左/右/皆可 手持蛋糕;对于每一条边,有长度为x的权值,可直接视作经过某一条边消耗的时间;而在行进过程中,可以通过消耗一定时间交替左右手。请你求出由起点抵达终点可以消耗的最短时间

主要思路:

1. Vector存图;

2. 通过拆分所有属性为M的点,将原图扩展;

3. Dijkstra跑一遍扩展后的图(优先队列)

4. 得出结果

ps:算法过程有待进一步优化。然鹅别的题还没搞完...溜溜球

咕~

*转载请注明出处 谢谢

#include<iostream>
#include<algorithm>
#include<queue>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>

#define ll long long
#define INF 1e12
using namespace std;
const int maxn = 1e5+10;
const int maxm = 2e5+10;

typedef pair<int, ll> PII;

int n, m, s, t;
ll x;
vector<PII> v[maxm];
char type[maxn];
ll dis[maxm];
bool vis[maxm];

struct node
{
    int id;
    ll val;
    //node(int a, ll b){id = a, val = b;}
    bool operator <(const node &t)const{
        return val > t.val;
    }//
} ;

inline void Add_Edge(int a, int b, int x)
{
    v[a].push_back({b, x});
    v[b].push_back({a, x});
}

ll dijkstra()
{
    for(int i = 0 ; i <= n * 2 + 1 ; i++){
        dis[i] = INF;
        vis[i] = false;
    }

    priority_queue<node> q;

    if(type[s] == 'M'){
        dis[0] = 0;
        q.push({0, 0});// {id, val}
    }else{
        dis[s] = 0;
        q.push({s, 0});
    }

    while(!q.empty()){
        node N = q.top();
        q.pop();
        int ID = N.id;

        if(vis[ID] == true)    continue;
        vis[ID] = true;

        int sz = (int)v[ID].size();
        for(int i = 0 ; i < sz ; i++){
            int now = v[ID][i].first;
            ll nowval = v[ID][i].second;
            if(!vis[now] && dis[ID] + nowval < dis[now]){
                dis[now] = dis[ID] + nowval;
                q.push({now, dis[now]});
            }
        }
    }

    if(type[t] == 'M'){
        return dis[n << 1 | 1];
    }else{
        return dis[t];
    }
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d%d%lld",&n,&m,&s,&t,&x);
        //s--; t--;
        scanf("%s",type+1);

        int nx = n << 1 | 1;//
        for(int i = 0 ; i <= nx ; i++){
            v[i].clear();
        }

        if(type[s] == 'M'){
            Add_Edge(0 ,s ,0);Add_Edge(s ,0 ,0);
            Add_Edge(0 ,s + n ,0);Add_Edge(s + n ,0 ,0);
        }
        if(type[t] == 'M'){
            Add_Edge(nx ,t ,0);Add_Edge(t ,nx ,0);
            Add_Edge(nx ,t + n ,0);Add_Edge(t + n ,nx ,0);
        }

        for(int i = 0 ; i < m ; i++){
            int a, b, d;
            cin >> a >> b >> d;
            //a--; b--;
            if(type[a] == type[b] && type[a] != 'M'){// LL || RR
                Add_Edge(a, b, d);Add_Edge(b, a, d);

            }else if(type[a] == 'L' && type[b] == 'R'){// LR
                Add_Edge(a, b, d + x);Add_Edge(b, a, d + x);

            }else if(type[a] == 'R' && type[b] == 'L'){// RL
                Add_Edge(a, b, d + x);Add_Edge(b, a, d + x);

            }else if(type[a] == 'M' && type[b] == 'L'){// ML
                Add_Edge(a, b, d);Add_Edge(b, a, d);
                Add_Edge(a + n, b, d + x);Add_Edge(b, a + n, d + x);

            }else if(type[a] == 'M' && type[b] == 'R'){// MR
                Add_Edge(a, b, d + x);Add_Edge(b, a, d + x);
                Add_Edge(a + n, b, d);Add_Edge(b, a + n, d);

            }else if(type[a] == 'L' && type[b] == 'M'){// LM
                Add_Edge(a, b, d);Add_Edge(b, a, d);
                Add_Edge(a, b + n, d + x);Add_Edge(b + n, a, d + x);

            }else if(type[a] == 'R' && type[b] == 'M'){// RM
                Add_Edge(a, b, d + x);Add_Edge(b, a, d + x);
                Add_Edge(a, b + n, d);Add_Edge(b + n, a, d);

            }else if(type[a] == 'M' && type[b] == 'M'){// MM
                Add_Edge(a, b, d);Add_Edge(b, a, d);
                Add_Edge(a + n, b + n, d);Add_Edge(b + n, a + n, d);
                Add_Edge(a, b + n, d + x);Add_Edge(b + n, a, d + x);
                Add_Edge(a + n, b, d + x);Add_Edge(b, a + n, d + x);

            }
        }

        ll ans = dijkstra();
        printf("%lld
",ans);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/ecustlegendn324/p/13446699.html