链接: 题目 .
题意:输入n m x 表示有n个点 m条边 终点是x,要求输出每个点到终点然后回来的最大值。
思路:如果正向跑,每个点开始跑一变dij求出每个点到终点距离和终点到每个点距离,肯定会T,所以改变一下思路,存一个正向图和一个反向图,正向图从x点跑一边最短路,可以得出终点到每个点的最短路,反向图也从x点跑一边最短路,因为反向图,所以可以得出每个点到终点的最短路。最后取两个dis相加的最大值。
代码
#include < iostream>
#include < cstdio>
#include < map>
#include < set >
#include < cmath>
#include < queue>
#include < stack>
#include < vector>
#include < cstring>
#include < algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define pb push_back
#define T int T ; scanf ( "%d" , & T ) ; while ( T -- )
const ll mod= 1e9 + 7 ;
const int maxn = 1010 ;
int n, m, k;
struct edge{
int to, dis;
bool operator< ( const edge & a) const {
return dis > a. dis;
}
} ;
vector< edge> g1[ maxn] ;
vector< edge> g2[ maxn] ;
int dis1[ maxn] ;
int dis2[ maxn] ;
int vis1[ maxn] ;
int vis2[ maxn] ;
void init ( ) {
for ( int i = 0 ; i < n+ 5 ; i ++ ) {
dis1[ i] = dis2[ i] = 1e9 ;
vis1[ i] = vis2[ i] = 0 ;
}
}
void dij1 ( ) {
priority_queue< edge> q;
edge e;
e. to = k;
e. dis = 0 ;
q. push ( e) ;
dis1[ k] = 0 ;
while ( ! q. empty ( ) ) {
edge p = q. top ( ) ;
q. pop ( ) ;
int u = p. to;
if ( vis1[ u] ) continue ;
vis1[ u] = 1 ;
for ( int i = 0 ; i < g1[ u] . size ( ) ; i ++ ) {
int v = g1[ u] [ i] . to;
if ( dis1[ v] > dis1[ u] + g1[ u] [ i] . dis) {
dis1[ v] = dis1[ u] + g1[ u] [ i] . dis;
edge ee;
ee. to = v;
ee. dis = dis1[ v] ;
q. push ( ee) ;
}
}
}
}
void dij2 ( ) {
priority_queue< edge> q;
edge e;
e. to = k;
e. dis = 0 ;
q. push ( e) ;
dis2[ k] = 0 ;
while ( ! q. empty ( ) ) {
edge p = q. top ( ) ;
q. pop ( ) ;
int u = p. to;
if ( vis2[ u] ) continue ;
vis2[ u] = 1 ;
for ( int i = 0 ; i < g2[ u] . size ( ) ; i ++ ) {
int v = g2[ u] [ i] . to;
if ( dis2[ v] > dis2[ u] + g2[ u] [ i] . dis) {
dis2[ v] = dis2[ u] + g2[ u] [ i] . dis;
edge ee;
ee. to = v;
ee. dis = dis2[ v] ;
q. push ( ee) ;
}
}
}
}
int main ( ) {
scanf ( "%d %d %d" , & n, & m, & k) ;
init ( ) ;
while ( m-- ) {
int u, v, w;
scanf ( "%d %d %d" , & u, & v, & w) ;
edge e;
e. to = v;
e. dis = w;
g1[ u] . push_back ( e) ;
e. to = u;
g2[ v] . push_back ( e) ;
}
dij1 ( ) ;
dij2 ( ) ;
int ans = 0 ;
for ( int i = 1 ; i <= n; i ++ ) {
ans = max ( ans, dis1[ i] + dis2[ i] ) ;
}
printf ( "%d\n" , ans) ;
return 0 ;
}