【HDU】3191 How Many Paths Are There 次短路计数
2014-08-22 16:38
337 查看
传送门:【HDU】3191 How Many Paths Are There
题目分析:就是朴素的次短路计数,但是题目可能有坑点,就是可能有边权为0的边(讨论版里说的),这时候优先队列的元素比较不仅需要比较权值,还需要当两点权值想同时先弹出拓扑序靠前的点。所以应该先做一次拓扑排序得到每个点的拓扑序,然后再用heap+dij求次短路以及次短路计数。
求次短路也就是比最短路多一维而已,看看代码很容易理解的。
代码如下:
题目分析:就是朴素的次短路计数,但是题目可能有坑点,就是可能有边权为0的边(讨论版里说的),这时候优先队列的元素比较不仅需要比较权值,还需要当两点权值想同时先弹出拓扑序靠前的点。所以应该先做一次拓扑排序得到每个点的拓扑序,然后再用heap+dij求次短路以及次短路计数。
求次短路也就是比最短路多一维而已,看看代码很容易理解的。
代码如下:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #define REP( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define REV( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define CLR( a , x ) memset ( a , x , sizeof a ) const int MAXN = 55 ; const int MAXH = 20005 ; const int MAXE = 20005 ; const int INF = 0x3f3f3f3f ; struct Edge { int v , c , n ; Edge () {} Edge ( int v , int c , int n ) : v ( v ) , c ( c ) , n ( n ) {} } ; struct Heap { int v , idx ; int k ; int key ; Heap () {} Heap ( int v , int idx , int k , int key ) : v ( v ) , idx ( idx ) , k ( k ) , key ( key ) {} bool operator < ( const Heap& a ) const { return v != a.v ? v < a.v : key < a.key ; } } ; struct priority_queue { Heap heap[MAXH] ; int point ; priority_queue () : point ( 1 ) {} void clear () { point = 1 ; } bool empty () { return point == 1 ; } void maintain ( int o ) { int x = o ; while ( o > 1 && heap[o] < heap[o >> 1] ) { swap ( heap[o] , heap[o >> 1] ) ; o >>= 1 ; } o = x ; int p = o , l = o << 1 , r = o << 1 | 1 ; while ( o < point ) { if ( l < point && heap[l] < heap[p] ) p = l ; if ( r < point && heap[r] < heap[p] ) p = r ; if ( p == o ) break ; swap ( heap[o] , heap[p] ) ; o = p , l = o << 1 , r = o << 1 | 1 ; } } void push ( int v , int idx , int k , int key ) { heap[point] = Heap ( v , idx , k , key ) ; maintain ( point ++ ) ; } void pop () { heap[1] = heap[-- point] ; maintain ( 1 ) ; } int front () { return heap[1].idx ; } int kind () { return heap[1].k ; } Heap top () { return heap[1] ; } } ; struct Shortest_Path_Algorithm { priority_queue q ; Edge E[MAXE] ; int H[MAXN] , cur ; int d[MAXN][2] ; bool vis[MAXN][2] ; int cnt[MAXN][2] ; int Q[MAXN] , head , tail ; int index ; int idx[MAXN] ; int in[MAXN] ; void init () { cur = 0 ; CLR ( H , -1 ) ; CLR ( in , 0 ) ; } void addedge ( int u , int v , int c ) { E[cur] = Edge ( v , c , H[u] ) ; H[u] = cur ++ ; } void dijkstra ( int s , int t ) { q.clear () ; CLR ( d , INF ) ; CLR ( vis , 0 ) ; CLR ( cnt , 0 ) ; d[s][0] = 0 ; cnt[s][0] = 1 ; q.push ( d[s][0] , s , 0 , idx[s] ) ; while ( !q.empty () ) { int u = q.front () ; int k = q.kind () ; q.pop () ; if ( vis[u][k] ) continue ; vis[u][k] = 1 ; for ( int i = H[u] ; ~i ; i = E[i].n ) { int v = E[i].v , c = E[i].c ; if ( d[v][0] > d[u][k] + c ) { d[v][1] = d[v][0] ; cnt[v][1] = cnt[v][0] ; q.push ( d[v][1] , v , 1 , idx[v] ) ; d[v][0] = d[u][k] + c ; cnt[v][0] = cnt[u][k] ; q.push ( d[v][0] , v , 0 , idx[v] ) ; } else if ( d[v][0] == d[u][k] + c ) { cnt[v][0] += cnt[u][k] ; } else if ( d[v][1] > d[u][k] + c ) { d[v][1] = d[u][k] + c ; cnt[v][1] = cnt[u][k] ; q.push ( d[v][1] , v , 1 , idx[v] ) ; } else if ( d[v][1] == d[u][k] + c ) { cnt[v][1] += cnt[u][k] ; } } } } void topo ( int n ) { index = 0 ; head = tail = 0 ; REP ( i , 0 , n ) if ( !in[i] ) Q[tail ++] = i ; while ( head != tail ) { int u = Q[head ++] ; idx[u] = index ++ ; for ( int i = H[u] ; ~i ; i = E[i].n ) if ( -- in[E[i].v] == 0 ) Q[tail ++] = E[i].v ; } } } G ; int n , m , q ; int s , t ; void scanf ( int& x , char c = 0 ) { while ( ( c = getchar () ) < '0' || c > '9' ) ; x = c - '0' ; while ( ( c = getchar () ) >= '0' && c <= '9' ) x = x * 10 + c - '0' ; } void solve () { int u , v , c ; G.init () ; while ( m -- ) { scanf ( u ) , scanf ( v ) , scanf ( c ) ; G.addedge ( u , v , c ) ; G.in[v] ++ ; } G.topo ( n ) ; G.dijkstra ( s , t ) ; printf ( "%d %d\n" , G.d[t][1] , G.cnt[t][1] ) ; } int main () { while ( ~scanf ( "%d%d%d%d" , &n , &m , &s , &t ) ) solve () ; return 0 ; }
相关文章推荐
- HDU 3191 How Many Paths Are There 【次短路计数】
- HDU_3191_How Many Paths Are There(次短路条数)
- hdu 3191 How Many Paths Are There(次短路+条数)
- HDU-3191 How Many Paths Are There(有向图次短路条数)
- HDU-3191 How Many Paths Are There 次最短路
- hdu 3191 How Many Paths Are There(次短路) 很纠结题目。。。
- hdu 1688 Sightseeing (次短路及次短路数)&&pku3255 Roadblocks &&3191 How Many Paths Are There
- HDU 3191 次短路 How Many Paths Are There
- HDU 3191 How Many Paths Are There
- hdu3191 How Many Paths Are There(次短路计数dp)
- HDU 3191 How Many Paths Are There
- HDU 3191 How Many Paths Are There
- hdu 3191 How Many Paths Are There (次短路径数)
- HDU 3191 How Many Paths Are There(SPFA)
- HDU-3191-How Many Paths Are There
- hdu 3191 How Many Paths Are There
- hdu 3191 How Many Paths Are There(求次短路径和次短路径条数)
- HDU 3139 How Many Paths Are There
- HDU3191-How many paths are there(次短路的长度及其个数)
- How Many Paths Are There(次最短路)