• 最短路


    1.dijkstra算法

    因为数组的实在太low...如果未用堆优化,很慢。

    所以直接学习堆优化的。

    学习笔记?度娘吧。没有空再写一遍啦。

    所以直接上代码。第一个是带注释的,第二个是没有注释的。

    模板。

    P4779 【模板】单源最短路径(标准版)

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <queue>
     5 #define R register
     6 #define MN 100005
     7 #define INF 0x7fffffff
     8 using namespace std;
     9 int n,m,s;//n个点,m条边,起始点s
    10 int d[MN];//起始点到i的最短距离 
    11 typedef pair<int ,int> p;//点对的第一个数i表示d[i],第二个数j表示这个点的编号 
    12 struct edge{int to,cost;};//结构体储存边的终点及权 
    13 vector <edge> G[MN];//每一个点及他的所有连点 
    14 inline int ri(){
    15     char c=getchar();int x=0,w=1;
    16     while(!isdigit(c)){if(c=='-')w=-1;c=getchar();}
    17     while( isdigit(c)){x=(x<<3)+(x<<1)+c-48;c=getchar();}
    18     return x*w;
    19 }
    20 inline void dijstra(int s){
    21     priority_queue<p,vector<p>,greater<p> >que;//定义按照d[i]从小到大 
    22     fill(d+1,d+n+1,INF);//初始化所有的d为INF 
    23     d[s]=0;que.push(p(0,s));//源点到自己的距离为0,这个点入队 
    24     while(!que.empty()){//只要队列还不为空 
    25         p q=que.top();que.pop();//取出d[i] 
    26         int v=q.second;//v是这个点 
    27         if(d[v]<q.first)continue;//如果队列某点的d值大于目前的它的最优值,则跳过这个点 
    28         for(int i=0;i<G[v].size();i++){//遍历它的每个连点 
    29             edge e=G[v][i];//定义一个e,表示当前这个点的连边及终点 
    30             if(d[e.to]>d[v]+e.cost){//如果目前到终点的最短距离比从源点先到当前点的最短距离加上直接连边来的大 
    31                 d[e.to]=d[v]+e.cost;//更新 
    32                 que.push(p(d[e.to],e.to));//可入队 
    33             }
    34         }    
    35     }
    36 }
    37 int main(){
    38     n=ri(),m=ri(),s=ri();
    39     int x,y,z;
    40     for(R int i=1;i<=m;++i){
    41         x=ri(),y=ri(),z=ri();//输入x和y之间的有向边z 
    42         edge e={y,z};//定义一个e.. 
    43         G[x].push_back(e); //添加到邻接表x中
    44     } 
    45     dijstra(s);//搜索源点 
    46     for(R int i=1;i<=n;i++)printf("%d ",d[i]);//输出 
    47     return 0;
    48 }
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <queue>
     5 #define R register
     6 #define MN 100005
     7 #define INF 0x7fffffff
     8 using namespace std;
     9 int n,m,s;
    10 int d[MN];
    11 typedef pair<int ,int> p;
    12 struct edge{int to,cost;};
    13 vector <edge> G[MN];
    14 inline void dijstra(int s){
    15     priority_queue<p,vector<p>,greater<p> >que;
    16     fill(d+1,d+n+1,INF);
    17     d[s]=0;que.push(p(0,s));
    18     while(!que.empty()){
    19         p q=que.top();que.pop();
    20         int v=q.second;
    21         if(d[v]<q.first)continue;
    22         for(int i=0;i<G[v].size();i++){
    23             edge e=G[v][i];
    24             if(d[e.to]>d[v]+e.cost){
    25                 d[e.to]=d[v]+e.cost;
    26                 que.push(p(d[e.to],e.to));
    27             }
    28         }    
    29     }
    30 }
    31 inline int ri(){
    32     char c=getchar();int x=0,w=1;
    33     while(!isdigit(c)){if(c=='-')w=-1;c=getchar();}
    34     while( isdigit(c)){x=(x<<3)+(x<<1)+c-48;c=getchar();}
    35     return x*w;
    36 }
    37 int main(){
    38     n=ri(),m=ri(),s=ri();
    39     int x,y,z;
    40     for(R int i=1;i<=m;++i){
    41         x=ri(),y=ri(),z=ri();
    42         edge e={y,z};
    43         G[x].push_back(e); 
    44     } 
    45     dijstra(s);
    46     for(R int i=1;i<=n;i++)printf("%d ",d[i]);
    47     return 0;
    48 }

     2.Floyd算法

    不过模板题了。

    优化起来貌似是堆优化的dijkstra更快吧???

    Floyd就是方便在它能求多组第i个点和第j个点的最短距离。

    n^3。

    放一道例题吧。

    P1364 医院设置

     1 #include<cstdio>
     2 #include <iostream>
     3 #define R register
     4 #define INF 0x7fffffff 
     5 using namespace std;
     6 int a[101],g[101][101];
     7 int n,ans=INF,tot;
     8 inline int ri(){
     9     char c=getchar();int x=0,w=1;
    10     while(!isdigit(c)){if(c=='-')w=-1;c=getchar();}
    11     while( isdigit(c)){x=(x<<3)+(x<<1)+c-48;c=getchar();}
    12     return x*w;
    13 }
    14 int main(){
    15     n=ri();
    16     for(R int i=1;i<=n;++i)
    17         for(R int j=1;j<=n;++j)
    18             g[i][j]=1000000;
    19     for(R int i=1;i<=n;++i){
    20         int l,r; g[i][i]=0;
    21         a[i]=ri(),l=ri(),r=ri();
    22         if(l)g[i][l]=g[l][i]=1;
    23         if(r)g[i][r]=g[r][i]=1; 
    24     }
    25     for(R int k=1;k<=n;++k)
    26         for(R int i=1;i<=n;++i)
    27             if(i!=k)
    28             for(R int j=1;j<=n;++j)   
    29                 if(i!=j&&k!=j&&g[i][k]+g[k][j]<g[i][j])
    30                       g[i][j]=g[i][k]+g[k][j];                
    31     for(R int i=1;i<=n;++i){
    32         tot=0;
    33         for(R int j=1;j<=n;++j)tot+=g[i][j]*a[j];
    34         ans=min(ans,tot);
    35     }
    36     printf("%d",ans);
    37     return 0;
    38 }
  • 相关阅读:
    Android笔记之开机自启
    Android笔记之广播
    Hive笔记之collect_list/collect_set(列转行)
    Hive笔记之数据库操作
    hive笔记之row_number、rank、dense_rank
    Linux Shell管道调用用户定义函数(使shell支持map函数式特性)
    Linux shell爬虫实现树洞网鼓励师(自动回复Robot)
    分享一些免费的接码平台(国外号码)
    爬虫技能之内容提取:如何从有不可见元素混淆的页面中抽取数据
    ctf writeup之程序员密码
  • 原文地址:https://www.cnblogs.com/flicker-five/p/10251360.html
Copyright © 2020-2023  润新知