zoukankan      html  css  js  c++  java
  • POJ 1511 最短路径之和(spfa或dijkstra+heap)

    题目链接: 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 }
    一毛原创作品,转载请注明出处。
  • 相关阅读:
    【codeforces 723F】stSpanning Tree
    struts2.0中struts.xml配置文件详解
    存储过程中调用JAVA程序段
    本不该逃避
    利用js实现对页面的自动刷新
    [转]从硬盘安装 RedHat Enterprise Linux Server 5 iso
    正则表达式使用
    利用XmlBean轻松读写xml(转)
    Struts2+Spring2+Hibernate3 web应用示例(七)
    在DWR中实现直接获取一个JAVA类的返回值的两种方法
  • 原文地址:https://www.cnblogs.com/yimao/p/2573576.html
Copyright © 2011-2022 走看看