zoukankan      html  css  js  c++  java
  • UVA 10801 Lift Hopping (最短路)

    最短路问题,不过起点不只是1个,终点也不止1个,因此把不同电梯的楼层分别编号,相邻楼层之间连边,不同电梯的相同楼层之间连边。

    dij的时候一次性把所有起点压到队列中,如果直接套版可以加一超级源点s和所有起点连一条dist为0的边。

    需要维护的信息:

    为了判断之前电梯有没有出现相同楼层,需要维护一个楼层到点编号的映射,为了判断终点,需要维护点编号到楼层的映射。

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,k;
    
    const int maxn = 100;
    typedef long long ll;
    
    vector<int> lift[5];
    int id[5][maxn]; //判断出现 和 换乘
    int flrId[5*maxn]; //结点对应的楼层,判断终点用
    int sp[5];//speed
    
    #define PB push_back
    
    struct Edge
    {
        int v,w;
    };
    int vcnt; //结点编号从1开始
    
    vector<Edge> edges;
    vector<int> G[maxn*5+1];
    
    void addEdge(int u,int v,int w)
    {
        G[u].PB(edges.size());
        edges.PB({v,w});
    }
    
    void AddEdge(int u,int v,int w)
    {
        addEdge(u,v,w);
        addEdge(v,u,w);
    }
    
    const ll INF = 0x3f3f3f3f3f3f3f3fLL;
    ll d[maxn];
    typedef pair<int,int> Node;
    #define fi first
    #define se second
    
    ll dijkstra(int tflr = k)
    {
        fill(d+1,d+1+vcnt,INF);
        priority_queue<Node,vector<Node>,greater<Node> > q;
        for(int i = 0; i < n; i++) if(id[i][0]){
            q.push(Node(0,id[i][0])); d[id[i][0]] = 0;
        }
        while(q.size()){
            Node x = q.top(); q.pop();
            int u = x.se;
            if(flrId[u] == tflr) return d[u];
            if(d[u] != x.fi) continue;
            for(int i = 0; i < G[u].size(); i++){
                Edge &e = edges[G[u][i]];
                if(d[e.v] > d[u] + e.w){
                    d[e.v] = d[u] + e.w;
                    q.push(Node(d[e.v],e.v));
                }
            }
        }
        return INF;
    }
    
    
    
    bool sscan_l(int &x,char *&s)//非负数
    {
        while(!isdigit(*s)){
            if(!*s) return false;
            s++;
        }
        x = *s-'0';
        while(s++,isdigit(*s)) x = x*10+*s-'0';
        return true;
    }
    
    char str[233];
    void read()
    {
        for(int i = 0; i < n; i++) scanf("%d",sp+i);
        scanf("
    ");
        for(int i = 0; i < n; i++) {
            gets(str); char *p = str;
            int floor; lift[i].clear();
            while(sscan_l(floor,p)){
                lift[i].PB(floor);
            }
        }
    }
    
    void buildGraph()
    {
        for(int i = 0; i < n; i++){
            int sz = lift[i].size();
            if(sz){
                int flr = lift[i][0];
                id[i][flr] = ++vcnt;
                flrId[vcnt] = flr;
                G[vcnt].clear();
                for(int k = 0; k < i; k++) if(id[k][flr]){
                    AddEdge(vcnt,id[k][flr],60);
                }
    
                for(int j = 1; j < sz; j++){
                    flr = lift[i][j];
                    id[i][flr] = ++vcnt;
                    flrId[vcnt] = flr;
                    G[vcnt].clear();
                    for(int k = 0; k < i; k++) if(id[k][flr]){
                        AddEdge(vcnt,id[k][flr],60);
                    }
    
                    int cost = (flr-lift[i][j-1])*sp[i];
                    AddEdge(vcnt-1,vcnt,cost);
                }
            }
        }
    }
    
    void init()
    {
        memset(id,0,sizeof(id));
        vcnt = 0;
        edges.clear();
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%d%d",&n,&k)){
            init();
            read();
            buildGraph();
            ll ans = dijkstra();
            if(ans<INF){
                printf("%lld
    ",ans);
            }else puts("IMPOSSIBLE");
        }
        return 0;
    }
  • 相关阅读:
    HDU 2116 Has the sum exceeded
    HDU 1233 还是畅通工程
    HDU 1234 开门人和关门人
    HDU 1283 最简单的计算机
    HDU 2552 三足鼎立
    HDU 1202 The calculation of GPA
    HDU 1248 寒冰王座
    HDU 1863 畅通工程
    HDU 1879 继续畅通工程
    颜色对话框CColorDialog,字体对话框CFontDialog使用实例
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4769522.html
Copyright © 2011-2022 走看看