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 ;
}
posted @ 2012-10-20 22:37  Misty_1  阅读(153)  评论(0编辑  收藏  举报