zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    block的是发送信号的线程,又不是处理槽函数的线程
  • 原文地址:https://www.cnblogs.com/ecustlegendn324/p/13446699.html
Copyright © 2011-2022 走看看