• poj 1511 Invitation Cards(spfa)


    题意:有个N个点的有向图,求从点1到其他各点,然后从其他各点回到点1的最小距离。

    思路:题意很容易理解,但是这题给的时间有点紧,不能用Dijksra 和Bellman_ford来做,只能有Spfa,先求出点1到到其他各点的最短距离,然后将边逆转,再求一下点1到各点的距离,求和就行了。明明思路是对的,但是愣是WA了一上午,不知道哪里错的,将discuss里提到的各种注意都改了,还是不对,差点疯了,结果不知道改了点什么就AC了,郁闷啊!!!

    代码:

    View Code
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <math.h>
    #define  N 1000050
    using namespace std ;
    
    typedef long long  ll ;
    const int INF = 1000000006 ;
    
    struct node
    {
        int e ;
        int val ;
        int next ;
    }p[N] , op[N] ;
    
    int head1[N] , head2[N] , q[N*10];
    ll dis[N] , sum ;
    int vist[N] , n , m , num ;
    
    void init1( )
    {
        memset( head1 , -1 , sizeof ( head1 )) ;
        memset( head2 , -1 , sizeof ( head2 )) ;
        num = 0 ;
    }
    
    void init2 ()
    {
        int i ;
        for ( i = 1 ; i <= n ; i++ )
        {
            dis[i] = INF ;
            vist[i] = 0 ;
        }
    }
    
    void add ( int x , int y , int z )
    {
        p[num].e = y ;
        p[num].val = z ;
        p[num].next = head1[x] ;
    
        op[num].e = x ;
        op[num].val = z ;
        op[num].next = head2[y] ;
    
        head1[x] = head2[y] = num++ ;
    }
    
    void Spfa()
    {
        int i , u , v ;
        queue<int>q ;
    
        sum = 0 ;
        init2();
        while( !q.empty()) q.pop();
        q.push( 1 ) ;
        dis[1] = 0 ;
        while ( !q.empty())
        {
            u = q.front();
            q.pop() ;
            vist[u] = 1 ;
            for ( i = head1[u] ; i != -1 ; i = p[i].next )
            {
                v = p[i].e ;
                if ( dis[v] > dis[u] + p[i].val )
                {
                    dis[v] = dis[u] + p[i].val ;
                    if ( !vist[v] )
                    {
                        vist[v] = 1 ;
                        q.push( v ) ;
                    }
                }
            }
            vist[u] = 0 ;
            //top++ ;
        }
        for ( i = 1 ; i <= n ; i++ )
        sum +=  dis[i] ;
    
        init2() ;
        //top = 0 ; tail = 1 ;
        while ( !q.empty()) q.pop();
        q.push( 1 ) ;
        dis[1] = 0 ;
        while ( !q.empty())
        {
            u = q.front();
            q.pop() ;
            vist[u] = 1 ;
            for ( i = head2[u] ; i != -1 ; i = op[i].next )
            {
                v = op[i].e ;
                if ( dis[v] > dis[u] + op[i].val )
                {
                    dis[v] = dis[u] + op[i].val ;
                    if ( !vist[v] )
                    {
                        vist[v] = 1 ;
                        q.push ( v ) ;
                    }
                }
            }
            vist[u] = 0 ;
            //top++ ;
        }
        for ( i = 1 ; i <= n ; i++ )
        sum +=  dis[i] ;
    
        //cout<<sum<<endl ;
        printf ( "%I64d\n" , sum ) ;
    }
    
    int main()
    {
        int i , x , y , z ;
        int cas ;
    
        scanf ( "%d" , &cas ) ;
        while ( cas-- )
        {
            scanf ( "%d%d" , &n , &m ) ;
            init1();
            for ( i = 1 ; i <= m ; i++ )
            {
                scanf ( "%d%d%d" , &x , &y , &z ) ;
                add ( x , y , z ) ;
            }
    
            Spfa() ;
        }
        return 0 ;
    }
  • 相关阅读:
    HDU 5919 分块做法
    HDU 3333 分块求区间不同数和
    CF 333E 计算几何+bitset优化
    hdu 1043 八数码--打表
    hdu 1043 八数码问题-A*搜索
    hdu 5919 主席树
    hiho1388 FFT/NTT
    HDU 5869区间CGD不同种类数---树状数组+map统计区间不同种类数(离线)
    HDU 5875 二分+st表
    HDU 5898 基础数位DP
  • 原文地址:https://www.cnblogs.com/misty1/p/2732715.html
Copyright © 2020-2023  润新知