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
  • 相关阅读:
    Just Do It:战胜拖延症(终极大法!)
    拖延是一种什么病
    数学之美系列二十三 谈谈香农第一定律
    深度挖掘
    当机器统治世界
    算法是如何秘密左右我们的行为方式
    比人类更强:为什么机器人终将也必将接手我们的工作?
    Google移动的未来在哪里?Google Now
    数学之美系列十九 马尔可夫链的扩展 贝叶斯网络 (Bayesian Networks)
    Matlab与COM应用(一)——COM技术概述
  • 原文地址:https://www.cnblogs.com/wangkaipeng/p/6442491.html
Copyright © 2011-2022 走看看