Dijkstra算法之六----邻接链表+优先队列实现Dijkstra算法
//poj 1511 Invitation Cards
#include<iostream> //Dijkstra+邻接链表+优先队列 1735MS!
#include<queue>
#define maxn 1000002
using namespace std;
struct Edge
{
int v;
int weight;
int next;
}Vertex[maxn];
int head[maxn],curr;
const __int64 inf=(__int64)1<<63-1;
int cases,p,e,i,j,edge[maxn][3];
void graph(int tag)
{
int u,v,w;
curr=0;
memset(head,-1,sizeof(head[0])*(p+1));
for(i=1;i<=e;++i)
{
u=edge[i][0];v=edge[i][1];w=edge[i][2];
if(tag)
swap(u,v);
Vertex[curr].v=v;
Vertex[curr].weight=w;
Vertex[curr].next=head[u];
head[u]=curr++;
}
}
struct Dis
{
int v,dis;
bool operator<(const Dis &a)const
{
return dis>a.dis;
}
};
__int64 distD[maxn],sum;
void Dijkstra(int u)
{
fill(distD,distD+p+1,inf);
distD[u]=0;
Dis fro,tmp;
fro.v=u;fro.dis=0;
priority_queue<Dis> col;
col.push(fro);
while(!col.empty())
{
fro=col.top();
col.pop();
if(distD[fro.v]<fro.dis)
continue;
for(i=head[fro.v];i!=-1;i=Vertex[i].next)
if( distD[fro.v]+Vertex[i].weight < distD[Vertex[i].v] )
{
distD[Vertex[i].v]=distD[fro.v]+Vertex[i].weight;
tmp.v=Vertex[i].v;tmp.dis=distD[Vertex[i].v];
col.push(tmp);
}
}
for(i=2;i<=p;++i)
sum+=distD[i];
}
int main()
{
scanf("%d",&cases);
while(cases--)
{
scanf("%d%d",&p,&e);
sum=0;
for(i=1;i<=e;++i)
scanf("%d%d%d",&edge[i][0],&edge[i][1],&edge[i][2]);
graph(0);
Dijkstra(1);
graph(1);
Dijkstra(1);
printf("%I64d\n",sum);
}
return 0;
}