hdu 1688 / poj 3463 #最短路个数

来源:互联网 发布:java 定时 编辑:程序博客网 时间:2024/06/05 08:26


最短路使用spfa

判断次短路开二维数组存储判断,注意队列存储的是pair<int , int > 第二个是对次短的标注,同时,vis(inq) , dist , num , 都要开二维

由于题目说一定存在一条路,所以一定不存在负环,可以不开cnt数组判断。


最后一定注意要判断dist[I][0]是否等于INF,如果等于,一定不能把他赋值给次短路dist[I][1] !!!

#include<algorithm>#include<iostream>#include<cstring>#include<vector>#include<cstdio>#include<queue>#include<map>#include<set>using namespace std;#define INF 0x3f3f3f3fconst int maxn = 1020 ;const int maxm = 10005;int point , road ;int u , v , w , st , ed ;struct Edge{    int st ,ed , cost ;    Edge( int temps ,int tempe , int tempc ) : st(temps) ,ed(tempe) ,cost(tempc) {}};vector<int> g[maxn] ;vector<Edge> edges ;bool vis[maxn][2] ; int d[maxn][2] , cnt[maxn][2] , num[maxn][2] ;int n ;void add_edge(int u , int v , int w ){    Edge temp = Edge( u , v , w ) ;    edges.push_back(temp) ;    g[u].push_back(edges.size()-1) ;}typedef pair< int , int >  p2 ;/*bool cmp ( p2 & a , p2 & b ){    return d[a.first][a.second] > d[b.first][b.second] ;}*/bool spfa(int u ){    int i , k ;    memset(vis , 0 , sizeof( vis )) ;    memset(cnt , 0 , sizeof( cnt )) ;    memset(num , 0 , sizeof( num )) ;    for( i = 0 ; i <= n ; i ++ ){        d[i][0] = d[i][1] = INF ;    }    d[u][0] = 0 ; vis[u][0] = true ; cnt[u][0] = 1 ; num[u][0] = 1 ;    queue<p2> q ; while ( ! q.empty() ) q.pop() ;    q.push( make_pair( u , 0 ) ) ;    while( !q.empty() ){        p2 temp = q.front() ; q.pop() ;        int t1 = temp.first , t2 = temp.second ;        vis[t1][t2] = 0 ;        for( k = 0 ; k < g[t1].size() ; k ++ ){            Edge e = edges[ g[t1][k] ] ;            if( d[e.ed][0] > d[t1][t2] + e.cost ){                if( d[e.ed][0] < INF ) /// very important , lose it will WA , fuck ..                 {                    d[e.ed][1] = d[e.ed][0] ;                    num[e.ed][1] = num[e.ed][0] ;                    if( !vis[e.ed][1]){                        vis[e.ed][1] = true ;                        q.push( make_pair(e.ed , 1 ) ) ;                    }                }                d[e.ed][0] = d[t1][t2] + e.cost ;                num[e.ed][0] = num[t1][t2] ;                if( !vis[e.ed][0] ){ /// fen liu                    vis[e.ed][0] = true ;                    //if( ++ cnt[e.ed][0] > n ) return false ;                    q.push( make_pair(e.ed , 0 ) ) ;                }            }else if( d[e.ed][0] == d[t1][t2] + e.cost ){                num[e.ed][0] += num[t1][t2] ;            }else if( d[e.ed][1] > d[t1][t2] + e.cost ){                d[e.ed][1] = d[t1][t2] + e.cost ;                num[e.ed][1] = num[t1][t2] ;                if( ! vis[e.ed][1] ){                    vis[e.ed][1] = true ;                    //if( ++ cnt[e.ed][1] > n ) return false ;                    q.push( make_pair(e.ed , 1)) ;                }            }else if( d[e.ed][1] == d[t1][t2] + e.cost ){                num[e.ed][1] += num[t1][t2] ;            }        }    }    return true ;}int main( ){    int m , a , b , c , kase;    scanf("%d" , &kase ) ;    while ( kase --  ){        scanf("%d %d" , &n , &m);        for( int i = 1 ; i <= n ; i ++ ) g[i].clear() ;        edges.clear() ; ///        for( int i = 0 ; i < m ; i ++ ){            scanf("%d %d %d" , &a , &b , &c ) ;            add_edge(a , b , c ) ;            //add_edge(b , a , c ) ;        }        scanf("%d %d",&a , &b) ;        spfa( a ) ;        //cout << d[b][0] << " " << d[b][1] << endl ;        //cout << num[b][0] << " " << num[b][1] << endl ;        if( d[b][1] == d[b][0] + 1 )            num[b][0] += num[b][1] ;        printf("%d\n" , num[b][0] ) ;    }    return 0 ;}
can you hear me 

阅读全文
0 0
原创粉丝点击