坐井观天

In the name of dream

导航

POJ 1511 最短路径之和(spfa或dijkstra+heap)

Posted on 2012-07-02 18:23  一毛_  阅读(528)  评论(0编辑  收藏  举报

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

题目大意:

  给定一个n(n<=1000000)个点的有向图,1为起点,求 1到所有点的最短路径之和 + 所有点到1的最短路径之和; 

 

分析:

  对于原图求一次最短路,再对反图求一次最短路即可;

  最短路可以使用spfa或者dijkstra+heap,下面都可以作为模版了很好用,深刻理解算法原理是关键;

  尤其是dijkstra+heap有多种写法,用下面的写法是比较好的(来自fhq队长);

 

代码:

poj1511 SPFA代码
 1 /*1511    Accepted    44324K    1688MS    C++    1871B    2012-07-02 17:29:59*/
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <iostream>
 6 #include <algorithm>
 7 #include <vector>
 8 using namespace std;
 9 
10 #define mpair make_pair
11 #define pii pair<int,int>
12 #define MM(a,b) memset(a,b,sizeof(a));
13 typedef long long lld;
14 typedef unsigned long long u64;
15 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
16 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
17 #define maxn 1000050
18 
19 int n,top,top2;
20 struct Edge{
21     int v,w;
22     Edge *next;
23 } *adj[maxn], e[maxn], *a2[maxn], e2[maxn];
24 void addedge(int u,int v,int w){
25     Edge *p= &e[top++];
26     p->v= v, p->w= w, p->next= adj[u], adj[u]= p;
27 }
28 void add2(int u,int v,int w){
29     Edge *p= &e2[top2++];
30     p->v= v, p->w= w, p->next= a2[u], a2[u]= p;
31 }
32 
33 const lld inf= 100000000000000LL;
34 lld d[maxn];
35 int que[maxn+10];
36 bool vis[maxn];
37 void spfa(Edge *(*a)){
38     int i, h=0, t= 0;
39     for(i=1;i<=n;++i) d[i]= inf, vis[i]= 0;
40     que[t++]= 1;
41     vis[1]= 1;
42     d[1]= 0;
43     while( h!=t ){
44         int u= que[h++]; if( h==maxn ) h= 0;
45         vis[u]= 0; ///!!!
46         for(Edge *p= a[u];p;p=p->next){
47             int v= p->v, w= p->w;
48             if( up_min( d[v], d[u]+p->w ) && !vis[v] ){
49                 vis[v]= 1;
50                 que[t++]= v; if( v==maxn ) v= 0;
51             }
52         }
53     }
54 }
55 
56 int main()
57 {
58     //freopen("poj1511.in","r",stdin);
59     int T,x,y,w,m,i;
60     cin>>T;
61     while(T--){
62         cin>>n>>m;
63         top= top2= 0;
64         for(i=1;i<=n;++i) adj[i]= a2[i]= 0;
65         while(m--){
66             scanf("%d%d%d", &x, &y, &w);
67             addedge( x, y, w );
68             add2( y, x, w );
69         }
70         lld ans= 0;
71         spfa( adj );
72         for(i=1;i<=n;++i) ans+= d[i];
73         spfa( a2 );
74         for(i=1;i<=n;++i) ans+= d[i];
75         cout<< ans <<endl;
76     }
77 }
poj1511 dijkstra+heap
 1 /*1511    Accepted    39440K    1860MS    C++    1958B    2012-07-02 18:17:29*/
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <iostream>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <queue>
 9 using namespace std;
10 
11 #define mpair make_pair
12 #define pii pair<int,int>
13 #define MM(a,b) memset(a,b,sizeof(a));
14 typedef long long lld;
15 typedef unsigned long long u64;
16 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
17 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
18 #define maxn 1000050
19 
20 int n,top,top2;
21 struct Edge{
22     int v,w;
23     Edge *next;
24 } *adj[maxn], e[maxn], *a2[maxn], e2[maxn];
25 void addedge(int u,int v,int w){
26     Edge *p= &e[top++];
27     p->v= v, p->w= w, p->next= adj[u], adj[u]= p;
28 }
29 void add2(int u,int v,int w){
30     Edge *p= &e2[top2++];
31     p->v= v, p->w= w, p->next= a2[u], a2[u]= p;
32 }
33 
34 const lld inf= 100000000000000LL;
35 lld d[maxn];
36 bool vis[maxn];
37 typedef pair< lld, int > plld;
38 priority_queue< plld, vector< plld >, greater< plld > >Q;
39 void dijkstra(Edge *(*a)){
40     for(int i=1;i<=n;++i) d[i]= inf;
41     d[1]= 0;
42     while( !Q.empty() ) Q.pop();
43     Q.push( mpair( 0, 1 ) );
44     while( !Q.empty() ){
45         lld dd= Q.top().first;
46         int u= Q.top().second;
47         Q.pop();
48         if( dd != d[u] ) continue;
49         for(Edge *p= a[u];p;p= p->next){
50             int v= p->v;
51             if( up_min( d[v], d[u] + p->w ) )
52                 Q.push( mpair( d[v], v ) );
53         }
54     }
55 }
56 
57 int main()
58 {
59     //freopen("poj1511.in","r",stdin);
60     int T,x,y,w,m,i;
61     cin>>T;
62     while(T--){
63         cin>>n>>m;
64         top= top2= 0;
65         for(i=1;i<=n;++i) adj[i]= a2[i]= 0;
66         while(m--){
67             scanf("%d%d%d", &x, &y, &w);
68             addedge( x, y, w );
69             add2( y, x, w );
70         }
71         lld ans= 0;
72         dijkstra( adj );
73         for(i=1;i<=n;++i) ans+= d[i];
74         dijkstra( a2 );
75         for(i=1;i<=n;++i) ans+= d[i];
76         cout<< ans <<endl;
77     }
78 }