Invitation Cards SPFA算法+静态链表

题意很明显:求单源最短路径。

但是里面的条件也很明显:P,Q均在1000000内。这个条件加上后,显然不能用Dijkstral了(看到上面限时8000MS就知道主要问题是时间了)。

求单源最短路径,用SPFA。以前写过,倒是好理解。另一问题是,这么多个点,如果用动态内存分配的话,malloc太耗时间了。所以要用静态链表了。

这次编码的过程中,刻意避免用任何多余的库函数,连队列都是自己的循环队列(不循环的话时间能省一些,但是空间要大几倍)。

越来越喜欢c语言,和什么东西都自己写的感觉了。只有自己写了才能真正懂。


/* * ===================================================================================== * * Filename: 1511.c * * Description: * * Version: 1.0 * Created: 2012年01月05日 12时36分07秒 * Revision: none * Compiler: gcc * * Author: MaZheng (blog.csdn.net/mazheng1989), mazheng19891019@gmail.com * Company: Dalian University Of Technology * * ===================================================================================== */ #include<stdio.h> #include <limits.h> #include <string.h> #define NUM 1000100 /* */ //please declare parameters here. struct Node { int v; int value; int next; }; struct Node Graph[2][NUM]; int adj[2][NUM]; int P,Q; int queue[NUM]; unsigned int dist[NUM]; char open[NUM]; long long output; //please declare functions here. void outputDist() { int i; for(i=1;i<=P;i++) printf("%d ",dist[i]); printf("\n"); } void spfa(int index) { memset(dist,INT_MAX,sizeof(int)*(P+1)); memset(open,0,sizeof(char)*(P+1)); int front=0,tail=0; tail=(tail+1)%NUM; queue[tail]=1; open[1]=1; dist[1]=0; int u,v,i,value; while(tail!=front)//(tail+1)%NUM!=front) { front=(front+1)%NUM; u=queue[front]; open[u]=0; for(i=adj[index][u];i!=-1;i=Graph[index][i].next) { v=Graph[index][i].v; value=Graph[index][i].value; if(dist[v]>dist[u]+value) { dist[v]=dist[u]+value; if(open[v]==0) { open[v]=1; tail=(tail+1)%NUM; queue[tail]=v; } } } } // outputDist(); } inline void addEdge(int index,int u,int v,int value,int n) { Graph[index][n].v=v; Graph[index][n].value=value; if(adj[index][u]==-1) { adj[index][u]=n; Graph[index][n].next=-1; } else { Graph[index][n].next=adj[index][u]; adj[index][u]=n; } } /*void outputGraph(int index) { int u; for(u=1;u<=P;u++) { int v=adj[index][u]; while(v!=-1) { printf("%d %d %d \n",u,Graph[index][v].v,Graph[index][v].value); v=Graph[index][v].next; } } }*/ inline void cal() { int i; for(i=2;i<=P;i++) { output+=dist[i]; } } int main() { if(freopen("input.txt","r",stdin)==NULL) perror("Can not open the input file!"); //input your ... int N,i,temp_u,temp_v,temp_value; scanf("%d",&N); while(N--) { scanf("%d %d",&P,&Q); memset(adj[0],-1,sizeof(int)*(P+1)); memset(adj[1],-1,sizeof(int)*(P+1)); for(i=0;i<Q;i++) { scanf("%d %d %d",&temp_u,&temp_v,&temp_value); addEdge(0,temp_u,temp_v,temp_value,i); addEdge(1,temp_v,temp_u,temp_value,i); } // outputGraph(0); // outputGraph(1); output=0; spfa(0); cal(); spfa(1); cal(); printf("%lld\n",output); } return 0; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值