poj 1511(SPFA+邻接表)

题目链接:http://poj.org/problem?id=1511

思路:题目意思很简单就是要求源点到各点的最短路之和,然后再求各点到源点的最短路之和,其实就是建两个图就ok了,其中一个建反图。1000000个点和1000000条边,一开始用SPFA+vector怎么都是TLE,然后换成邻接表就过了=.=。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<vector>
 6 #include<queue>
 7 using namespace std;
 8 #define MAXN 1000100
 9 #define inf 1LL<<60
10 
11 struct Edge{
12     int v,w,next;
13 }edge1[MAXN*10],edge2[MAXN*10];
14 
15 int head1[MAXN],head2[MAXN];
16 long long dist[MAXN];
17 bool mark[MAXN];
18 int n,m,NE;
19 
20 void Insert(Edge *edge,int *head,int u,int v,int w)
21 {
22     edge[NE].v=v;
23     edge[NE].w=w;
24     edge[NE].next=head[u];
25     head[u]=NE;
26 }
27 
28 
29 long long SPFA(Edge *edge,int *head,int u)
30 {
31     memset(mark,false,(n+2)*sizeof(bool));
32     for(int i=1;i<=n;i++)dist[i]=inf;
33     dist[u]=0;
34     queue<int>Q;
35     Q.push(u);
36     while(!Q.empty()){
37         u=Q.front();
38         Q.pop();
39         mark[u]=false;
40         for(int i=head[u];i!=-1;i=edge[i].next){    
41             int v=edge[i].v,w=edge[i].w;
42             if(dist[u]+w<dist[v]){
43                 dist[v]=dist[u]+w;
44                 if(!mark[v]){ mark[v]=true;Q.push(v); }
45             }
46         }
47     }
48     long long ans=0;
49     for(int i=2;i<=n;i++)ans+=dist[i];
50     return ans;
51 }
52 
53 int main()
54 {
55     int _case,u,v,w;
56     scanf("%d",&_case);
57     while(_case--){
58         scanf("%d%d",&n,&m);
59         NE=0;
60         memset(head1,-1,(n+2)*sizeof(int));
61         memset(head2,-1,(n+2)*sizeof(int));
62         while(m--){
63             scanf("%d%d%d",&u,&v,&w);
64             Insert(edge1,head1,u,v,w);
65             Insert(edge2,head2,v,u,w);//建反图
66             NE++;
67         }
68         printf("%lld\n",SPFA(edge1,head1,1)+SPFA(edge2,head2,1));
69     }
70     return 0;
71 }
72 
73 
74         
75             
View Code

 

posted @ 2013-07-24 19:42  ihge2k  阅读(1153)  评论(0编辑  收藏  举报