Untitled
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