zoukankan      html  css  js  c++  java
  • 单源最短路问题

    1.bellman-ford

     1 #include<iostream>
     2 #define INF 1000000
     3 using namespace std;
     4 struct edge
     5 {
     6     int from,to,cost;
     7     edge(){}
     8     edge(int ff,int tt,int cc)
     9     {
    10         from=ff;
    11         to=tt;
    12         cost=cc;
    13     }
    14 };
    15 const int maxn=105;
    16 const int maxe=10005;
    17 int d[maxn];
    18 edge es[maxe];
    19 int v,e;
    20 
    21 void bellman_ford(int s)
    22 {
    23     fill(d,d+v,INF);
    24     d[s]=0;
    25     while(true)
    26     {
    27         bool update=false;
    28         for(int i=0;i<e;i++)
    29         {
    30             edge e=es[i];
    31             if(d[e.from]!=INF&&d[e.to]>d[e.from]+e.cost)
    32             {
    33                 d[e.to]=d[e.from]+e.cost;
    34                 update=true;
    35             }
    36         }
    37         if(!update) break;
    38     }
    39     for(int i=0;i<v;i++)
    40     {
    41         cout<<d[i]<<endl;
    42     }
    43 }
    44 //如果返回true则存在复圈
    45 bool find_negative_loop()
    46 {
    47     fill(d,d+v,INF);
    48     for(int i=0;i<v;i++)
    49     {
    50         for(int j=0;j<e;j++)
    51         {
    52             edge e=es[j];
    53             if(d[e.to]>d[e.from]+e.cost)
    54             {
    55                 d[e.to]=d[e.from]+e.cost;
    56 
    57                 //如果第n次仍然更新了,则存在负圈
    58                 if(i==v-1) return true;
    59             }
    60         }
    61     }
    62     return false;
    63 }
    64 int main()
    65 {
    66     cin>>v>>e;
    67     int from,to,cost;
    68     for(int i=0;i<e;i++)
    69     {
    70         cin>>from>>to>>cost;
    71         from--;
    72         to--;
    73         es[i]=edge(from,to,cost);
    74     }
    75     //cout<<find_negative_loop();
    76     bellman_ford(0);
    77     return 0;
    78 }
    View Code

    2.dijkstra

     1 #include<bits/stdc++.h>
     2 #define INF 1000000
     3 using namespace std;
     4 const int maxn=1010;
     5 //邻接矩阵形式
     6 int cost[maxn][maxn];
     7 int used[maxn];
     8 int d[maxn];
     9 int n;
    10 int prev[maxn];//最短路上所有前驱结点
    11 vector<int> get_path(int t)
    12 {
    13     vector<int> path;
    14     for(;t!=-1;t=prev[t])
    15         path.push_back(t);//不断沿着prev[t]走直到t=s
    16     reverse(path.begin(),path.end());
    17     return path;
    18 }
    19 void dijkstra(int s)
    20 {
    21     fill(d,d+n,INF);
    22     fill(used,used+n,0);
    23     fill(prev,prev+n,-1);
    24     d[s]=0;
    25     while(true)
    26     {
    27         int v=-1;
    28         for(int u=0; u<n; u++)
    29         {
    30             if(!used[u]&&(v==-1||d[u]<d[v]))
    31             {
    32                 v=u;
    33             }
    34         }
    35         if(v==-1) break;//所有节点都计算完毕
    36         used[v]=1;
    37         for(int u=0; u<n; u++)
    38         {
    39             if(d[u]>d[v]+cost[v][u])
    40             {
    41                 d[u]=d[v]+cost[v][u];
    42                 prev[u]=v;
    43             }
    44         }
    45     }
    46     for(int i=0; i<n; i++)
    47     {
    48         cout<<d[i]<<endl;
    49     }
    50 
    51     vector<int> path=get_path(n-1);
    52     for(int i=0;i<path.size();i++)
    53     {
    54         cout<<path[i]<<" ";
    55     }
    56 }
    57 
    58 int main()
    59 {
    60     cin>>n;
    61     for(int i=0; i<n; i++)
    62     {
    63         for(int j=0; j<n; j++)
    64         {
    65             cin>>cost[i][j];
    66         }
    67     }
    68     dijkstra(0);
    69     return 0;
    70 }
    71 /*
    72 测试数据 教科书 P189 G6 的邻接矩阵 其中 数字 1000000 代表无穷大
    73 6
    74 1000000 1000000 10      100000      30      100
    75 1000000 1000000 5       1000000     1000000 1000000
    76 1000000 1000000 1000000 50          1000000 1000000
    77 1000000 1000000 1000000 1000000     1000000 10
    78 1000000 1000000 1000000 20          1000000 60
    79 1000000 1000000 1000000 1000000     1000000 1000000
    80 结果:
    81 D[0]   D[1]   D[2]   D[3]   D[4]   D[5]
    82  0   1000000   10     50     30     60
    83 */
    View Code

    3.堆优化的dijkstra

     1 #include<iostream>
     2 #include<vector>
     3 #include<queue>
     4 #define INF 1000000
     5 using namespace std;
     6 typedef pair<int,int> P; //first代表最短距离,second代表顶点的编号
     7 //邻接表
     8 struct edge
     9 {
    10     int to,cost;
    11     edge(int tt,int cc)
    12     {
    13         to=tt;
    14         cost=cc;
    15     }
    16 };
    17 const int maxn=105;
    18 vector<edge> G[maxn];
    19 int d[maxn];
    20 int n;
    21 void heap_dijkstra(int s)
    22 {
    23     fill(d,d+n,INF);
    24     priority_queue<P,vector<P>,greater<P> > que;
    25     que.push(P(0,s));
    26     d[s]=0;
    27     while(!que.empty())
    28     {
    29         P p=que.top();
    30         que.pop();
    31         int v=p.second;
    32         if(p.first>d[v]) continue;
    33         for(int i=0;i<G[v].size();i++)
    34         {
    35             edge e=G[v][i];
    36             if(d[e.to]>d[v]+e.cost)
    37             {
    38                 d[e.to]=d[v]+e.cost;
    39                 que.push(P(d[e.to],e.to));
    40             }
    41         }
    42     }
    43     for(int i=0;i<n;i++)
    44         cout<<d[i]<<endl;
    45 }
    46 int main()
    47 {
    48     cin>>n;
    49     int from,to,cost;
    50     for(int i=0;i<n;i++)
    51     {
    52         cin>>from>>to>>cost;
    53         from--;
    54         to--;
    55         G[from].push_back(edge(to,cost));
    56         G[to].push_back(edge(from,cost));
    57     }
    58 
    59     heap_dijkstra(0);
    60     return 0;
    61 }
    View Code

    4.floyd_warshall

     1 #include<iostream>
     2 #include<memory.h>
     3 #define INF 1000000
     4 using namespace std;
     5 const int maxn=105;
     6 int d[maxn][maxn];
     7 int n;
     8 //任意两点间的最短路问题,dp
     9 void floyd_warshall()
    10 {
    11     for(int i=0; i<n; i++)
    12         d[i][i]=0;
    13 
    14     for(int k=0; k<n; k++)
    15         for(int i=0; i<n; i++)
    16             for(int j=0; j<n; j++)
    17                 d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
    18 
    19     for(int i=0; i<n; i++)
    20         cout<<d[0][i]<<endl;
    21 }
    22 int main()
    23 {
    24     memset(d,INF,sizeof(d));
    25     cin>>n;
    26     for(int i=0; i<n; i++)
    27         for(int j=0; j<n; j++)
    28             cin>>d[i][j];
    29 
    30     floyd_warshall();
    31     return 0;
    32 }
    View Code

    5.spfa

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<vector>
     4 #include<queue>
     5 using namespace std;
     6 #define inf 99999999
     7 typedef struct dd
     8 {
     9     int a,d;
    10 }node;
    11 int dis[20005],n;
    12 vector<node> maps[20005];
    13 void sets()
    14 {
    15     for(int i=1;i<=n;i++)
    16     {
    17         dis[i]=inf;
    18     }
    19 }
    20 void spfa()
    21 {
    22     queue<int> q;
    23     int b[20005]={0},t;//b数组标识节点是否在队列中
    24     q.push(1);//起点入队
    25     b[1]=1;   //标记
    26     dis[1]=0; //距离
    27     while(!q.empty())
    28     {
    29         //队首元素出队
    30         t=q.front();
    31         q.pop();
    32         //标记
    33         b[t]=0;
    34         //这个点作为起点的路径有多少
    35         int len=maps[t].size();
    36         int a;
    37         for(int i=0;i<len;i++)
    38         {
    39             //这条路径的终点
    40             a=maps[t][i].a;
    41             if(dis[a]>maps[t][i].d+dis[t])
    42             {
    43                 dis[a]=maps[t][i].d+dis[t];
    44                 if(!b[a])
    45                 {
    46                     b[a]=1;
    47                     q.push(a);
    48                 }
    49             }
    50         }
    51     }
    52 }
    53 int main()
    54 {
    55     int m,a,b,l;
    56     node Now;
    57     while(scanf("%d%d",&n,&m)==2)
    58     {
    59         sets();
    60         while(m--)
    61         {
    62             scanf("%d%d%d",&a,&b,&l);
    63             Now.a=b;
    64             Now.d=l;
    65             maps[a].push_back(Now);
    66         }
    67         spfa();
    68         for(int i=2;i<=n;i++)
    69         {
    70             printf("%d
    ",dis[i]);
    71         }
    72     }
    73     return 0;
    74 }
    View Code
  • 相关阅读:
    WINCE创建快捷方式
    Android初级开发第四讲系统中一些属性的区别
    Android初级开发第六讲Activity的布局
    Android初级开发第三讲项目中控件的学习
    物联网产业链及市场分
    读《浪潮之巅》有感
    Hello China V1.75成功运行于Lenovo超级本上
    Android初级开发第七讲特效和数据传递处理
    Android中级第二讲制作搜索页面,使用TextWatcher
    电信运营商物联网实践建议
  • 原文地址:https://www.cnblogs.com/wangkaipeng/p/6442491.html
Copyright © 2011-2022 走看看