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
  • 相关阅读:
    IOS中多版本,多设备类型支持注意事项
    runtime
    网络搜集各种iOS开源类库
    Foudation框架常用结构体和常用类
    iOS开发-正则表达式的使用方法
    Github上的iOS资料-个人记录
    iOS应用程序多语言本地化
    星期判断
    【设定本地通知为周一到周五提醒, 周末不提醒解决办法】
    iOS9 HTTPS解决办法
  • 原文地址:https://www.cnblogs.com/wangkaipeng/p/6442491.html
Copyright © 2011-2022 走看看