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;
}
?

 

posted @ 2018-08-07 21:04  xayata  阅读(141)  评论(0编辑  收藏  举报