zoukankan      html  css  js  c++  java
  • kuangbin_ShortPath P (HDU 4725)

    很有挑战的一题 直接暴力建图的话毫无疑问O(n^2)会TLE 每层虚拟一个点又会让没有点的层也能连过去

    参考kuangbin菊苣的方法每层用了两个虚拟点 n+i*2-1 是入口 n+i*2 是出口 然后建单向边就可以了

    VA了一次 因为MAXN应该比数据量大两倍 不小心忽略了 至于MAXM直接开到了1e7

    #include <iostream>
    #include <string>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <queue>
    #include <map>
    #include <vector>
    #include <set>
    #include <algorithm>
    #define INF 0x3F3F3F3F
    using namespace std;
    
    const int MAXN = 1e6 + 10;
    const int MAXM = 2e7 + 10;
    
    typedef pair<int, int> pii;
    struct cmp{
        bool operator ()(const pii a, const pii b){
            return a.first > b.first;
        }
    };
    
    int size, head[MAXN], point[MAXM], nxt[MAXM], val[MAXM];
    int t, n, m, c, dist[MAXN];
    
    void init()
    {
        size = 0;
        memset(head, -1, sizeof head);
    }
    
    inline void add(int from, int to, int value)
    {
        val[size] = value;
        point[size] = to;
        nxt[size] = head[from];
        head[from] = size++;
    }
    
    void dij(){
        priority_queue<pii, vector<pii>, cmp> q;
        memset(dist, 0x3f, sizeof dist);
        q.push(make_pair(0, 1));
        dist[1] = 0;
        while(!q.empty()){
            pii u = q.top();
            q.pop();
            if(u.first > dist[u.second]) continue;
            for(int i = head[u.second]; ~i; i = nxt[i]){
                if(dist[point[i]] > dist[u.second] + val[i]){
                    dist[point[i]] = dist[u.second] + val[i];
                    q.push(make_pair(dist[point[i]], point[i]));
                }
            }
        }
    }
    
    int main()
    {
        scanf("%d", &t);
        for(int kase = 1; kase <= t; kase++){
            init();
            scanf("%d%d%d", &n, &m, &c);
            for(int i = 1; i <= n; i++){
                int layer;
                scanf("%d", &layer);
                add(n + 2*layer - 1, i, 0);
                add(i, n + 2*layer, 0);
            }
            for(int i = 1; i < n; i++){
                add(n + 2*i, n + 2*(i+1) - 1, c);
                add(n + 2*(i+1), n + 2*i - 1, c);
            }
            int u, v, w;
            for(int i = 1; i <= m; i++){
                scanf("%d%d%d", &u, &v, &w);
                add(u, v, w);
                add(v, u, w);
            }
            
            dij();
            printf("Case #%d: %d
    ", kase, dist[n] == INF ? -1 : dist[n]);
        }
        return 0;
    }
  • 相关阅读:
    树莓派3(Raspbain系统)安装.net环境
    CSS3实现鼠标悬停扩展效果
    WINIO64位模拟键鼠操作
    json在线校验
    阿里云ali-oss图片增加水印
    babel使用中不想使用 严格模式 如何去除?
    记录移动端html界面中底部输入框触发焦点时键盘会把输入框遮挡的问题
    nodejs 项目,请求返回Invalid Host header问题
    css如何画出类似原生的线条?
    js回到顶部 动画速度 (自己记录)
  • 原文地址:https://www.cnblogs.com/quasar/p/5131553.html
Copyright © 2011-2022 走看看