POJ 1511题

//题目类型:最短路类型
//算法实现:Dijkstra(邻接表+优先级队列) ,使用此算法效率非常高,只有2094MS
#include <stdio.h>
#include <iostream>
//#include <conio.h>
#include <queue>
using namespace std;
#define arraysize 1000001
#define maxData 1000000001
typedef unsigned long long u64_T;
typedef struct node
{
     int v;        //终点
     u64_T w;      //费用
     node *next;
}node;
typedef struct pnode
{
     int v;
     u64_T length;
     bool operator<(const pnode &temp) const
     {
          return length>temp.length;
     }
}pnode;
node *adj[arraysize];
node *readj[arraysize];
node edges[arraysize];  //正向邻接表
node reedges[arraysize]; //逆向邻接表
bool final[arraysize];
u64_T d[arraysize];
int P,Q;
int edgenum,reedgenum;
void addEdge(int start,int end,u64_T w)
{
     node *temp = &edges[edgenum++];
     temp->v = end;
     temp->w = w;
     temp->next=adj[start];
     adj[start] = temp;
}
void addReEdge(int start,int end,u64_T w)
{
     node *temp = &reedges[reedgenum++];
     temp->v = end;
     temp->w = w;
     temp->next = readj[start];
     readj[start] = temp;
}
u64_T SPFA(int s,int flag)     //使用flag区别是正向还是逆向
{
     int i,j;
     priority_queue<pnode> myqueue; //使用优先级队列实现
     pnode frontnode,tempnode;
     memset(final,0,sizeof(final)); //final用于标记该节点是否在队列中
     for(i=1;i<P+1;++i)  d[i] = maxData; //初始化:设置为无穷大
     d[s] = 0;  //源点的距离设置为0
     final[s] = true;
     frontnode.v = s;
     frontnode.length = 0;
     myqueue.push(frontnode);
     while(!myqueue.empty()) //SPFA算法的终止条件,队列为空
     {
          int frontv = myqueue.top().v;
          myqueue.pop();
          final[frontv] = true;
          node *nodep = NULL;
          if(flag ==1)     
              nodep = adj[frontv];
          else
              nodep = readj[frontv];    
          for(;nodep;nodep=nodep->next) //对该点相邻的边进行松弛操作
          {
               int tempu = nodep->v;
               u64_T templength = nodep->w;
               if(!final[tempu] && d[tempu]>d[frontv]+templength)
               {
                   d[tempu] = d[frontv]+templength;
                   tempnode.v = tempu;
                   tempnode.length = d[tempu];
                   myqueue.push(tempnode);
               }
          }
     }
     u64_T sum = 0;
     for(i=1;i<=P;++i)
     {
          sum += d[i];
     }
     return sum;
}
int main()
{
     //freopen("1.txt","r",stdin);
     int N;
     int i,j;
     int start,end;
     u64_T w;
     scanf("%d",&N);
     while(N--)
     {        
           u64_T sum = 0;
           edgenum = 0;           //初始化边的数目
           reedgenum = 0;
           scanf("%d%d",&P,&Q);
           for(i=1;i<=P;++i)   //初始化邻接指针
           {
                adj[i] = NULL;
                readj[i] = NULL;
           }
           for(i=1;i<=Q;++i)
           {
                scanf("%d%d%I64d",&start,&end,&w); //注意:读取unsigned long long 时,使用%I64d,不要使用%llu,若使用此此题读取出错。
                addEdge(start,end,w);
                addReEdge(end,start,w);           
           }
           sum = SPFA(1,1)+SPFA(1,2);
           printf("%llu\n",sum); //注:__int64的输出              
     }    
     //getch();
     return 0;
}

 

posted @ 2010-04-28 22:42  北海小龙  阅读(333)  评论(0编辑  收藏  举报