HDU1535最短路 (SPFA/DIJKSTRA + priority_queue)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1535

 

 

此题为有向图中,求出发点到各顶点距离及从各顶点返回的总距离之和,也就是最短路问题,

 

刚开始时用到SPFA+priority,可 1328ms 的运行时间让我不能接受,

于是又用Dijkstra+priority写了一下,由于没有考虑到当前出队点可能是已经计算过的点,而且

用了for(i=1;i<=n;i++)的循环wa了一次,修改之后以578ms AC,可见Dijkstra效率还是远超

SPFA的,不过SPFA可以求得带负边权的最短路问题,从这一点上来说,还是值得学习的~

 

以下是两个代码:主要为两实现算法函数,

(SPFA+priority_queue)3761315 2011-04-04 11:00:04  Accepted 1535   1328MS     39636K 1538 B C++ ㄉ ㄉ

(Dijkstra+priority_queue)3761418 2011-04-04 11:22:13  Accepted 1535   578MS    39936K 2142 B C++ ㄉ ㄉ

 

 

#include<stdio.h> #include<string.h> #include<queue> #define M 1000008 #define INF 0x7fffffff using namespace std; typedef struct talQNode{ int v,dis; bool operator < (const talQNode &a) const { return a.dis<dis; } }QNode; typedef struct{//静态邻接表 int u,v,c; int next; }Edge; Edge edge[2][M]; int head[2][M]; int inq[M]; int dis[2][M]; int n,m,e1,e2; priority_queue<QNode>q; void AddEdge(int u,int v,int c) { edge[0][e1].u=u;edge[0][e1].v=v; edge[0][e1].c=c;edge[0][e1].next=head[0][u]; head[0][u]=e1++; edge[1][e2].u=v;edge[1][e2].v=u; edge[1][e2].c=c;edge[1][e2].next=head[1][v]; head[1][v]=e2++; } /* void SPFA(int f) { QNode cur,next; int u,v,tmp; for(u=1;u<=n;u++){ inq[u]=false; dis[f][u]=INF; } inq[1]=true;dis[f][1]=0; cur.v=1;cur.dis=0; q.push(cur); while(!q.empty()){ cur=q.top();q.pop(); u=cur.v;inq[u]=false; for(tmp=head[f][u];tmp!=-1;tmp=edge[f][tmp].next){ v=edge[f][tmp].v; if(dis[f][v]-dis[f][u]>edge[f][tmp].c){ dis[f][v]=dis[f][u]+edge[f][tmp].c; if(!inq[v]){ inq[v]=true; next.v=v; next.dis=dis[f][v]; q.push(next); } } } } } */ void Dijkstra(int f) { QNode cur,next; int u,v,tmp; //while(!q.empty()) q.pop(); for(u=1;u<=n;u++){ inq[u]=false; dis[f][u]=INF; } cur.v=1;cur.dis=0; q.push(cur); while(!q.empty()){//由于相同点可能多次更新距离而入队, //所以出队的点可能是已经出过队的, //不能用指定次数的循环,WA了一次 cur=q.top();q.pop(); u=cur.v; if(inq[u]) continue;//增加是否标记的判断,解决循环的问题 inq[u]=true;dis[f][u]=cur.dis; for(tmp=head[f][u];tmp!=-1;tmp=edge[f][tmp].next){ if(inq[edge[f][tmp].v]) continue; v=edge[f][tmp].v; if(dis[f][v]-dis[f][u]>edge[f][tmp].c){ dis[f][v]=dis[f][u]+edge[f][tmp].c; next.v=v;next.dis=dis[f][v]; q.push(next); } } } } int main() { int t,i,j,u,v,c,ans; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); e1=e2=0; memset(head,-1,sizeof(head)); for(i=0;i<m;i++){ scanf("%d%d%d",&u,&v,&c); AddEdge(u,v,c); } //SPFA(0);SPFA(1); Dijkstra(0);Dijkstra(1); ans=0; for(i=0;i<2;i++){ for(j=1;j<=n;j++) ans+=dis[i][j]; } printf("%d/n",ans); } return 0; }  






 

 

 

 

你可能感兴趣的:(c,算法,struct)