zoukankan      html  css  js  c++  java
  • bzoj4400

    /*
     * 此题同bzoj2725
     * 增加了枚举边的操作 
     */
    #include <bits/stdc++.h>
     
    const int N = 2e5 + 10;// oo = 999999999;
     
    #define LL long long
     
    const LL oo = 9e18;
     
    int n, m, S, T;
    int Short_path[N], Snum[N], Tnum[N], Id[N], path_js;
    bool vis[N];
    int head[N], now;
    struct Node {int u, v, w, nxt;} G[N << 1];
    LL dis_s[N], dis_t[N];
    LL Minn[N << 2], Ans[N];
     
    inline void Add(int u, int v, int w) {
        G[++ now].v = v, G[now].w = w, G[now].nxt = head[u], head[u] = now;
    }
     
    struct Node_ {
        int u; LL dis;
        bool operator < (const Node_ a) const {return dis > a.dis;}
    };
     
    std:: priority_queue <Node_> Q;
     
    void Dijkstra(int start, LL dis_[]) {
        for(int i = 1; i <= n; i ++) dis_[i] = oo, vis[i] = 0;
        Node_ now; now = (Node_) {start, 0}; dis_[start] = 0;
        Q.push(now);
        while(!Q.empty()) {
            Node_ topp = Q.top();
            Q.pop();
            if(vis[topp.u]) continue;
            vis[topp.u] = 1;
            for(int i = head[topp.u]; ~ i; i = G[i].nxt) {
                int v = G[i].v;
                if(dis_[v] > dis_[topp.u] + G[i].w) {
                    dis_[v] = dis_[topp.u] + G[i].w;
                    Q.push((Node_) {v, dis_[v]});
                }
            }
        }
    }
     
    inline void Bfs(int x, LL dis_[], int bel[]) {
        std:: queue <int> Q1;
        Q1.push(Short_path[x]);
        bel[Short_path[x]] = x;
        while(!Q1.empty()) {
            int topp = Q1.front();
            Q1.pop();
            for(int i = head[topp]; ~ i; i = G[i].nxt) {
                int v = G[i].v;
                if(!Id[v] && !bel[v] && dis_[v] == dis_[topp] + G[i].w) {
                    bel[v] = x;
                    Q1.push(v);
                }
            }
        }
    }
     
    #define lson jd << 1
    #define rson jd << 1 | 1
     
    void Sec_G(int l ,int r, int jd, int x, int y, LL num) {
        if(x <= l && r <= y) {
            Minn[jd] = std:: min(Minn[jd], (LL)num);
            return ;
        }
        int mid = (l + r) >> 1;
        if(x <= mid) Sec_G(l, mid, lson, x, y, num);
        if(y > mid)  Sec_G(mid + 1, r, rson, x, y, num);
    }
     
    void Dfs_tree(int l, int r, int jd) {
        if(l == r) {
            Ans[l] = Minn[jd];
            return ;
        }
        int mid = (l + r) >> 1;
        Minn[lson] = std:: min(Minn[lson], Minn[jd]);
        Minn[rson] = std:: min(Minn[rson], Minn[jd]);
        Dfs_tree(l, mid, lson), Dfs_tree(mid + 1, r, rson);
    }
     
    #define gc getchar()
     
    inline LL read() {
        LL x = 0; char c = gc;
        while(c < '0' || c > '9') c = gc;
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
        return x;
    }
     
    bool visit[N << 1];
     
    int main() {
        n = read(), m = read();
        for(int i = 1; i <= (N << 2); i ++) Minn[i] = oo;
        for(int i = 1; i <= n; i ++) head[i] = -1;
        for(int i = 1; i <= m; i ++) {
            int u = read(), v = read(), w = read();
            Add(u, v, w), Add(v, u, w);
        }
        S = 1, T = n;
        Dijkstra(S, dis_s);
        Dijkstra(T, dis_t);
        for(int i = S; i != T; i = i) {
        //  visit[i] = 1;
            Short_path[++ path_js] = i;
            Id[i] = path_js;
            for(int j = head[i]; ~ j; j = G[j].nxt) {
                if(dis_t[i] == G[j].w + dis_t[G[j].v]) {
                    i = G[j].v; 
                    visit[j] = 1;
                    break;
                }
            }
        }
        Short_path[path_js + 1] = T, Id[T] = path_js + 1;
        for(int i = 1; i <= path_js; i ++) Bfs(i, dis_s, Snum);
        for(int i = path_js + 1; i >= 1; i --) Bfs(i, dis_t, Tnum);
        for(int i = 1; i <= n; i ++) {
            for(int j = head[i]; ~ j; j = G[j].nxt) {
                int v = G[j].v;
                if(visit[j]) continue;
                if(Snum[i] < Tnum[v] && Snum[i] && Tnum[v]) {
                    Sec_G(1, path_js, 1, Snum[i], Tnum[v] - 1, dis_s[i] + G[j].w + dis_t[v]);
                }               
            }
        }
        Dfs_tree(1, path_js, 1);
        LL Dis = 0, js;
        for(int i = 1; i <= path_js; i ++) {
            if(Ans[i] > Dis && Ans[i] != oo) Dis = Ans[i], js = 1;
            else if(Ans[i] == Dis) js ++;
        }
        if(Dis == dis_s[T]) js += m - path_js;
        std:: cout << Dis << " " << js;
        return 0;
    }
    ?
  • 相关阅读:
    各种版本控制器的作用
    mybatis的一些特殊符号标识(大于,小于,等于,不等于)
    struts2的作用是什么
    js中给数组添加元素的方法有哪些
    springmvc中拦截器配置格式
    js中require()的用法----JS如何连接数据库执行sql语句或者建立数据库连接池
    hover()函数的用法
    error和exception的不同与相同
    cookie和session的区别有哪些
    数据库连接池的工作机制是什么
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9439457.html
Copyright © 2011-2022 走看看