1. 程式人生 > 實用技巧 >hdu 6805 Deliver the Cake(最短路+分層圖)

hdu 6805 Deliver the Cake(最短路+分層圖)

題意:n個點m條邊無向圖,求s到t的最少時間,某些地方需要特定的手拿蛋糕,L表示該點必須左手拿,R同理,M沒有要求。
解法:dis[i][j] j表示左手或右手到達i點的最少時間。

#include <bits/stdc++.h>
typedef long long ll ;
#define int ll
int quickpow(int a , int b , int mo){int ans = 1 ;while(b){ if(b&1){ans = ans * a % mo ;}b >>= 1 ;a = a * a % mo ;}return ans ;}
using namespace std ;
#define INF 0x3f3f3f3f
const double PI = acos(-1.0);
const int maxn = 1e5+9;
const int mod = 1e9+7;
int n , m , b , e , t ;

char s[maxn];
int dis[maxn][3] ;//0表示從左手過來的,1表示從右手過來的
bool vis[maxn][3];
vector<pair<int,int>>g[maxn];
struct node{
    int u , w , k ;
    bool operator < (const node e) const{
        return w > e.w;
    }
    node(int _u , int _w , int _k){
        u = _u , w = _w , k = _k;
    }
};
int turn(char c){
    if(c == 'L') return 0 ;
    if(c == 'R') return 1 ;
    return 2 ;
}

void dijkstra(int u){
    for(int i = 1 ; i <= n ; i++){
        dis[i][0] = dis[i][1] = 1e18 ;
        vis[i][0] = vis[i][1] = false;
    }
    priority_queue<node>q;
    if(s[u] == 'M'){
        dis[u][0] = 0 ;
        dis[u][1] = 0 ;
        q.push(node(u , dis[u][0] , 0));
        q.push(node(u , dis[u][1] , 1));
    }else if(s[u] == 'L'){
        dis[u][0] = 0 ; 
        q.push(node(u , dis[u][0] , 0));
    }else{
        dis[u][1] = 0 ;
        q.push(node(u , dis[u][1] , 1));
    }
    while(!q.empty()){
        node now = q.top() ; q.pop();
        int u = now.u , nk = now.k;
        vis[u][nk] = 1 ;
        for(auto j : g[u]){
            int v = j.first , w = j.second ;int k = turn(s[v]);
            if(vis[v][k])continue;
            if((nk == k || k == 2) && dis[v][nk] > dis[u][nk] + w){
                dis[v][nk] = dis[u][nk] + w ;
                q.push(node(v , dis[v][nk] , nk));
            }else if(nk != k && dis[v][k] > dis[u][nk] + w + t){
                dis[v][k] = dis[u][nk] + w + t ;
                q.push(node(v , dis[v][k] , k));
            }
        }
    }
}
void init(){
    for(int i = 1 ; i <= n ; i++){
        g[i].clear();
    }
}
void Solve(){
    cin >> n >> m >> b >> e >> t >> s+1 ;
    init();
    for(int i = 1 ; i <= m ; i++){
        int u , v , w ;
        cin >> u >> v >> w ;
        g[u].push_back({v , w});
        g[v].push_back({u , w});
    }  
    dijkstra(b);
    cout << min(dis[e][0] , dis[e][1]) << endl;
}
  
  
signed main(){
    #ifdef ONLINE_JUDGE
    #else
        freopen("D:\\c++\\in.txt", "r", stdin);
        freopen("D:\\c++\\out.txt", "w", stdout);
    #endif
    int t ;
    cin >> t ;
    while(t--)
        Solve();
}