ZOJ 2008 Invitation Cards(邻接表+spfa||dijkstra)

来源:互联网 发布:吾生有涯而知无涯图片 编辑:程序博客网 时间:2024/05/17 21:53

这题收获很大,求1到所有点的最短距离,然后再求所有点到1的最短距离,把所有的边反一下在求1到所有点的最短距离就是所有点到1的最短距离了.

刚开始用new直接就TLE了还以为是最短路算法问题,试了dijkstra还有spfa都是TLE,后来看了解题报告才发现必须要用静态邻接表才能过,

最后运行时间:dijkstra 290ms,spfa 280ms.还是spfa稍好一点,并且易于实现

#include <iostream>#include <cstdio>#include <memory.h>#include <queue>using namespace std;const int maxn=1000010;struct Edge{int u,v,w,next;}g[2][maxn];struct node{int i,v;node(int ii=0,int vv=0):i(ii),v(vv){}bool operator<(const node &rhs)const{return v>rhs.v;}};int n,q,dis[maxn],head[2][maxn];bool vis[maxn];/*long long spfa(int idx){long long ans=0;queue<int>q;memset(dis,0X45,sizeof(int)*(n+1));memset(vis,0,n+1);dis[1]=0;q.push(1);vis[1]=1;while(q.size()){int t=q.front();q.pop();vis[t]=0;int ne=head[idx][t];for (;ne!=-1;ne=g[idx][ne].next){if(dis[g[idx][ne].v]>dis[t]+g[idx][ne].w){dis[g[idx][ne].v]=dis[t]+g[idx][ne].w;if(!vis[g[idx][ne].v]){q.push(g[idx][ne].v);vis[g[idx][ne].v]=1;}}}}for (int i=1;i<=n;++i){ans+=dis[i];}return ans;}*/long long dijkstra(int idx){long long ans=0;priority_queue<node>q;memset(dis,0X45,sizeof(int)*(n+1));memset(vis,0,n+1);dis[1]=0;q.push(node(1,0));while(q.size()){node t=q.top();q.pop();if(vis[t.i])continue;vis[t.i]=1;ans+=dis[t.i];int ne=head[idx][t.i];for (;ne!=-1;ne=g[idx][ne].next){if(dis[g[idx][ne].v]>dis[t.i]+g[idx][ne].w&&!vis[g[idx][ne].v]){dis[g[idx][ne].v]=dis[t.i]+g[idx][ne].w;q.push(g[idx][ne].v);}}}return ans;}int main(){int t;scanf("%d",&t);while (t--){scanf("%d%d",&n,&q);for (int i=0;i<=n;++i){head[0][i]=head[1][i]=-1;}for (int i=0;i<q;++i){int u,v,w;scanf("%d%d%d",&u,&v,&w);g[0][i].u=u;g[0][i].v=v;g[0][i].w=w;g[0][i].next=head[0][u];head[0][u]=i;g[1][i].u=v;g[1][i].v=u;g[1][i].w=w;g[1][i].next=head[1][v];head[1][v]=i;}long long ans=dijkstra(0)+dijkstra(1);printf("%lld\n",ans);}return 0;}


原创粉丝点击