POJ 3013 SPFA

这个题很有意思,其实就是求出最短路径,再用最短路径值*结点值的和。通过这题,又找到了编程的一个bug,总是想省空间,结果就只能悲剧了,还是先相乘后强制转化的问题,必须出错的!第一次用比__int64还大的数据类型usigned long long,另外熟悉了一下宏,感觉还不错。对最短路径又有了新的想法,理解算法很有好处啊!!

#include<iostream>
#include<queue>
#define MAXN 50005
#define ULL  unsigned long long
#define INF 184467440737095516151
using namespace std;

struct Node
{
       int v;
       ULL price;
       Node *next;
}Edge[MAXN<<1],*ptr[MAXN];

int N,E,EdgeNum;
ULL dist[MAXN];

void addEdge( int u,int v,ULL price )
{
     Node *p=&Edge[EdgeNum++];
     p->v=v;
     p->price=price;
     p->next=ptr[u];
     ptr[u]=p;
}
bool inQ[MAXN];
bool changed[MAXN];
void SPFA()
{
     memset( changed,0,sizeof(changed) );
     memset( inQ,0,sizeof(inQ) );
     memset( dist,0xFF,sizeof(dist) );
     dist[1]=0;
     queue<int>myQueue;
     myQueue.push(1);
     while( !myQueue.empty() )
     {
            int u=myQueue.front();
            myQueue.pop();
            Node *p=ptr[u];
            inQ[u]=false;
            while( p )
            {
                   if( dist[p->v]>dist[u]+p->price )
                   {
                       dist[p->v]=dist[u]+p->price;
                       changed[p->v]=true;
                       if( !inQ[p->v] )
                       {
                           inQ[p->v]=true;
                           myQueue.push(p->v);
                       }
                   }
                   p=p->next;
            }
     }
}

int main()
{
    int degree[MAXN];
    int i,j;
    int T;
    scanf( "%d",&T );
    while( T-- )
    {
           EdgeNum=0;
           scanf( "%d %d",&N,&E );
           for( i=1;i<=N;i++ )
                ptr[i]=NULL;
           for( i=1;i<=N;i++ )
                scanf( "%d",°ree[i] );
           int u,v;
           ULL price;
           for( i=1;i<=E;i++ )
           {
                scanf( "%d %d %llu",&u,&v,&price );
                addEdge( u,v,price );
                addEdge( v,u,price );
           }
           SPFA();
           unsigned long long ans=0;
           for( i=2;i<=N;i++ )
                if( changed[i]==false )
                {
                    printf( "No Answer\n" );
                    goto BY;
                }
           for( i=2;i<=N;i++ )
                ans+=dist[i]*degree[i];
           printf( "%llu\n",ans );
           BY:
             ;      
    }
    return 0;
}


你可能感兴趣的:(编程,算法,null)