Untitled

 avatar
unknown
plain_text
9 months ago
2.9 kB
15
Indexable
// quintessential
#include <bits/stdc++.h>
#define fi first
#define se second
#define all(x) x.begin(), x.end()
#define bit(x, i) ( ( x >> i ) & 1 )
#define mask(i) ( (1LL) << (i) )
#define cook '\n'
#define Task "graph"

using namespace std ;

const int dx[] = {-1, 0, 1, 0} ;
const int dy[] = {0, -1, 0, 1} ;
const int mod = 1e9 + 7 ;
const int maxn = 3e5 + 5 ;

struct Edge {
    int u, v;
    long long danger, cost ;
    void inp(void) {
        cin >> u >> v >> danger >> cost ;
    }
    bool operator < ( const Edge &other ) const {
        if ( danger != other.danger ) return danger < other.danger ;
        return cost < other.cost ;
    }
};

int numNode, numPath ;
Edge e[maxn] ;

void inp() {
    cin >> numNode >> numPath ;
    for ( int i = 1; i <= numPath; i++ ) e[i].inp() ;
    sort(e + 1, e + numPath + 1) ;
}

vector<int> lab ;

int findRoot(int u) {
    return ( lab[u] < 0 ? u : lab[u] = findRoot(lab[u])) ;
}

void joint(int u, int v) {
    int parU = findRoot(u), parV = findRoot(v) ;
    if ( parU == parV ) return;
    if ( lab[parU] > lab[parV] ) swap(parU, parV) ;
    lab[parU] += lab[parV] ;
    lab[parV] = parU ;
}

vector<pair<int, long long>> g[maxn] ;

long long findBestWay(int limit) {
    // build graph
    for ( int i = 1; i <= limit; i++ ) {
        int u = e[i].u, v = e[i].v ;
        long long cost = e[i].cost ;
        g[u].push_back(make_pair(v, cost)) ;
        g[v].push_back(make_pair(u, cost)) ;
    }
    // dijkstra
    const long long INF = 1e19 ;
    vector<long long> minCost(numNode + 1, INF) ;
    priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq ;
    pq.push(make_pair(0, 1)) ; minCost[1] = 0 ;
    while ( !pq.empty() ) {
        long long curCost = pq.top().fi ;
        int u = pq.top().se ;
        pq.pop() ;
        if ( curCost != minCost[u] ) continue ;

        for ( const pair<int, long long> &other : g[u] ) {
            int v = other.fi ;
            long long cost = other.se ;

            if ( curCost + cost < minCost[v] ) {
                minCost[v] = curCost + cost ;
                pq.push(make_pair(minCost[v], v)) ;
            }
        }
    }
    return minCost[numNode] ;
}

signed main() {
    ios_base::sync_with_stdio(0) ;
    cin.tie(nullptr) ;
    if ( fopen(Task".inp", "r") ) {
        freopen(Task".inp", "r", stdin) ;
        freopen(Task".out", "w", stdout) ;
    }
    inp() ; lab.assign(numNode + 1, -1) ;
    int limit = 1;
    for ( int i = 1; i <= numPath; i++ ) {
        joint(e[i].u, e[i].v) ;
        if ( findRoot(1) == findRoot(numNode) ) {
            limit = i ;
            while ( limit + 1 <= numPath && e[limit + 1].danger == e[i].danger ) limit++ ;
            break ;
        }
    }
    cout << e[limit].danger << ' ' << findBestWay(limit) ;
}
Editor is loading...
Leave a Comment