POJ1511(Invitation Cards)

本文详细介绍了解决最短路问题的方法,包括迪杰斯特拉算法、SPFA算法,并针对数据结构的选择进行了优化。文章还讨论了溢出问题的处理,以及如何通过静态链表替代动态链表来提升程序效率。通过实例分析,读者可以深入理解最短路问题的求解策略及其优化要点。

题目链接

最短路的题,这题时间限制较严,第一次用dijkstra果断挂掉,后来改用SPFA写,由于我用的数据结构是动态链表,所以还是TLE,改为静态链表后就AC了。在这个过程中还贡献了一次WA,因为最后结果用32位会溢出,题中说的总价格不会超过1000000000是单个最短路不会超,而最后的结果是n-1个结点的最短路之和。

View Code
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <memory.h>
 4 #define INF 1000000001
 5 #define N 1000001
 6 #define MIN(a,b) ((a)<(b)?(a):(b))
 7 struct node
 8 {
 9     int v,w;
10     struct node *next;
11 };
12 int cnt;
13 struct node edge[2*N];
14 struct node *a[N],*b[N];
15 int dist[N],n,m;
16 int queue[N],front,rear;
17 char vis[N];
18 void addEdge(int u,int v,int w)
19 {
20     struct node *p,*q;
21     p=&edge[cnt++];
22     q=&edge[cnt++];
23     p->v=v,p->w=w;
24     p->next=a[u],a[u]=p;
25     q->v=u,q->w=w;
26     q->next=b[v],b[v]=q;
27 }
28 void SPFA(int u,struct node *list[])
29 {
30     int i,v;
31     struct node *p;
32     front=rear=0;
33     memset(vis,0,sizeof(vis));
34     for(i=0;i<n;i++)    dist[i]=(i==u?0:INF);
35     queue[rear++]=u;
36     while(front!=rear)
37     {
38         i=queue[front],front=(front+1)%N;
39         vis[i]=0;
40         for(p=list[i];p;p=p->next)
41         {
42             v=p->v;
43             if(dist[v]>dist[i]+p->w)
44             {
45                 dist[v]=dist[i]+p->w;
46                 if(!vis[v])
47                 {
48                     vis[v]=1;
49                     queue[rear]=v,rear=(rear+1)%N;
50                 }
51             }
52         }
53     }
54 }
55 int main()
56 {
57     int i,j,k,d,t;
58     long long ans;
59     scanf("%d",&t);
60     while(t--)
61     {
62         scanf("%d%d",&n,&m);
63         cnt=0;
64         for(i=0;i<m;i++)
65         {
66             scanf("%d%d%d",&j,&k,&d);
67             j--,k--;
68             addEdge(j,k,d);
69         }
70         ans=0;
71         SPFA(0,a);
72         for(i=1;i<n;i++)   ans+=dist[i];
73         SPFA(0,b);
74         for(i=1;i<n;i++)   ans+=dist[i];
75         printf("%lld\n",ans);
76         memset(a,0,sizeof(a));
77         memset(b,0,sizeof(b));
78     }
79     return 0;
80 }

 

转载于:https://www.cnblogs.com/algorithms/archive/2012/04/22/2465052.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值