enlaces a los temas: https://vjudge.net/contest/362170#problem/I
Significado de las preguntas:
Usted Mn puntos y conjuntos, dentro del conjunto de puntos puede llegar a unos de otros, es el tiempo que tarda T I (1≤i≤M). Ahora había dos personas desde el punto 1 y el punto n, y pidieron a los dos hombres se encontraron más rápido el tiempo es la cantidad, y la salida de los dos lugares de encuentro (puede haber más de lo que las localidades)
ideas:
Se establece para cada conjunto de fuente puntual, y la fuente para el punto de ajuste de peso está configurado para una fuente puntual de pesos son w / 2, a fin de hacer que el conjunto de pesos entre el valor del punto w
A continuación, ejecute de nuevo desde el principio, más corta, comenzó a correr a partir de la travesía n más corto para encontrar el mínimo
#pragma optimize GCC (3, "Ofast", "en línea") // O3优化 #pragma GCC optimize (2) // O2优化 #include <algoritmo> #include < string > #include < string .h> #include < vector> #include <mapa> #include <pila> #include < set > #include <cola> #include <math.h> #include <cstdio> #include <iomanip> #include <time.h> # include <bitset> # include<cmath> #include <sstream> #include <iostream> #include <cstring> #define LL largo largo #define ls cabeceo << 1 #define rs (NOD << 1) 1 #define par pii <int, int> #define mp make_pair #define pb push_back #define INF 0x3f3f3f3f #define max (a, b) (a> b a:? b) #define min (a, b) (a <b a:? b) const dobles eps = 1E- 10 ; const int maxN = 2E6 + 10 ; const LL mod = 1e9 + 7 ; int sgn ( doble a) { volver a <del EPS? - 1 : a <eps? 0 : 1 ;} usando espacio de nombres std; int cabeza [maxN]; int DIS1 [maxN], DIS2 [maxN]; bool vis [maxN]; int cnt; struct Edge { int a, al lado, val; } borde [maxN]; void init () { cnt = 0 ; memset (cabeza, - 1 , sizeof (cabeza)); } Void add_edge ( int u,int v, int w) { borde [cnt] .a = v; borde [cnt] .val = w; borde [cnt] .Next = cabeza [u]; cabeza [u] = cnt ++ ; } Void dijstra ( int s, int dist []) { para ( int i = 0 ; i <maxN; i ++ ) dist [i] = INF; memset (vis, falso , sizeof (vis)); priority_queue <pii, vector <pii>, mayor <pii >> q; dist [s]= 0 ; q.push ({dist [s], s}); mientras que (! q.empty ()) { int ahora = q.top () segundos.; q.pop (); si (vis [ahora]) continuará ; vis [ahora] = verdadero ; para ( int i = cabeza [ahora]; i = - 1 ; i = borde [i] .A continuación) { int v = borde [i] .a; si (dist [v]> dist [ahora] + borde [i] .val) { dist [v] = dist [ahora] + borde [i] .val; q.push ({dist [v], v}); } } } } Int main () { int T; scanf ( " % d " , y T); int t = 1 ; mientras que (T- ) { int n, m; scanf ( " % d% d " , y n, y m); en eso(); para ( int i = 1 ; i <= m; i ++ ) { int v; int s; scanf ( "% d% d "& v, y s); para ( int k = 1 ; k <= S; k ++ ) { int y; scanf ( " % d " , y y); add_edge (n + i, y, v ); add_edge (y, n + i, v); } } dijstra ( 1 , DIS1); dijstra (n, DIS2); printf ( " caso #% d: " , t ++ ); int ans = INF; para( Int i = 1 ; i <= n; i ++ ) { ans = min (max (DIS1 [i], DIS2 [i]), ans); } Si (American National Standard> = INF) { printf ( " Mal John \ n " ); continuar ; } Printf ( " % .0lf \ n " , ans / 2.0 ); bool fl = false ; para ( int i = 1 ; i <= n; i ++ ) { si (DIS1 [i] <= ans && DIS2 [i] <=ans) { si (! fl) { printf ( " % d " , i); fl = verdadero ; } Demás printf ( " % d " , i); } } Printf ( " \ n " ); } Volver 0 ; }