zoukankan      html  css  js  c++  java
  • 【luogu 3371】【模板】单源最短路径

    题目描述

    如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。

    输入输出格式

    输入格式:

    第一行包含三个整数N、M、S,分别表示点的个数、有向边的个数、出发点的编号。

    接下来M行每行包含三个整数Fi、Gi、Wi,分别表示第i条有向边的出发点、目标点和长度。

    输出格式:

    一行,包含N个用空格分隔的整数,其中第i个整数表示从点S出发到点i的最短路径长度(若S=i则最短路径长度为0,若从点S无法到达点i,则最短路径长度为2147483647)

    输入输出样例

    输入样例#1:
    4 6 1
    1 2 2
    2 3 2
    2 4 1
    1 3 5
    3 4 3
    1 4 4
    输出样例#1:
    0 2 4 3

    说明

    时空限制:1000ms,128M

    数据规模:

    对于20%的数据:N<=5,M<=15

    对于40%的数据:N<=100,M<=10000

    对于70%的数据:N<=1000,M<=100000

    对于100%的数据:N<=10000,M<=500000

    样例说明:

    题解:

    Dijkstra:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<queue>
     6 #include<vector>
     7 using namespace std;
     8 const int INF=0x3f;
     9 const int maxn=500050;
    10 int d[maxn];bool vis[maxn];
    11 vector<int> G[10004];
    12 int n,m,sta;
    13 struct Edge{int u,v,w;}e[maxn];
    14 struct node{
    15     int d,u;
    16     bool operator < (const node &sky) const {
    17         return sky.d<d;
    18     }
    19 };
    20 void dijkstra(int sta){
    21     priority_queue<node> q;
    22     memset(d,INF,sizeof(d)); d[sta]=0;
    23     q.push((node){0,sta});
    24     while(!q.empty()){
    25         node x=q.top();q.pop();
    26         int u=x.u;
    27         if(vis[u]) continue;
    28         for(int i=0;i<G[u].size();i++){
    29             Edge &edges=e[G[u][i]];
    30             if(d[edges.v]>d[u]+edges.w){
    31                 d[edges.v]=d[u]+edges.w;
    32                 q.push((node){d[edges.v],edges.v});
    33             }
    34         }
    35     }
    36 }
    37 int main(){
    38     scanf("%d%d%d",&n,&m,&sta);
    39     for(int i=1;i<=m;i++){
    40         scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
    41         G[e[i].u].push_back(i);
    42     }
    43     dijkstra(sta);
    44     for(int i=1;i<=n;i++){
    45         if(d[i]!=0x3f3f3f3f) printf("%d ",d[i]);
    46         else printf("2147483647 ");
    47     }
    48     return 0;
    49 }

    Bellman-Ford:

    不优化(70):

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<queue>
     6 #include<vector>
     7 #define maxn 500005
     8 using namespace std;
     9 int read(){
    10     int x=0,f=1;char ch=getchar();
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 int n,m,sta;
    16 int u[maxn],v[maxn],w[maxn],d[maxn];
    17 int main(){
    18     n=read(),m=read(),sta=read();
    19     for(int i=1;i<=n;i++) d[i]=0x3f3f3f3f;
    20     d[sta]=0;
    21     for(int i=1;i<=m;i++) u[i]=read(),v[i]=read(),w[i]=read();
    22     for(int i=1;i<n;i++){
    23         for(int j=1;j<=m;j++){
    24             if(d[v[j]]>d[u[j]]+w[j]){
    25                 d[v[j]]=d[u[j]]+w[j];
    26             }
    27         }
    28     }
    29     for(int i=1;i<=n;i++){
    30         if(d[i]!=0x3f3f3f3f) printf("%d ",d[i]);
    31         else printf("2147483647 ");
    32     }
    33     return 0;
    34 }

    剪枝优化(100):

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<queue>
     6 #include<vector>
     7 #define maxn 500005
     8 using namespace std;
     9 int read(){
    10     int x=0,f=1;char ch=getchar();
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 int n,m,sta;
    16 int u[maxn],v[maxn],w[maxn],d[maxn];
    17 int main(){
    18     n=read(),m=read(),sta=read();
    19     for(int i=1;i<=n;i++) d[i]=0x3f3f3f3f;
    20     d[sta]=0;
    21     for(int i=1;i<=m;i++) u[i]=read(),v[i]=read(),w[i]=read();
    22     for(int i=1;i<n;i++){
    23         bool flag=0;
    24         for(int j=1;j<=m;j++){
    25             if(d[v[j]]>d[u[j]]+w[j]){
    26                 flag=true;
    27                 d[v[j]]=d[u[j]]+w[j];
    28             }
    29         }
    30         if(!flag) break;
    31     }
    32     for(int i=1;i<=n;i++){
    33         if(d[i]!=0x3f3f3f3f) printf("%d ",d[i]);
    34         else printf("2147483647 ");
    35     }
    36     return 0;
    37 }

    spfa:

    邻接表版:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<queue>
     6 #include<vector>
     7 #define maxn 10005
     8 using namespace std;
     9 int read(){
    10     int x=0,f=1;char ch=getchar();
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 struct edge{int v,w;};
    16 vector<edge>G[maxn];
    17 int d[maxn],n,m,sta;
    18 bool inq[maxn];
    19 void add(int u,int v,int w){G[u].push_back((edge){v,w});}
    20 void spfa(int sta){
    21     memset(d,-1,sizeof(d));
    22     d[sta]=0;
    23     memset(inq,0,sizeof(inq));
    24     queue<int> q;
    25     q.push(sta);
    26     while(!q.empty()){
    27         int k=q.front(); q.pop();
    28         inq[k]=0;
    29         for(int i=0;i<G[k].size();i++){
    30             edge &e=G[k][i];
    31             if(d[e.v]==-1||d[k]+e.w<d[e.v]){
    32                 d[e.v]=d[k]+e.w;
    33                 if(!inq[e.v]){
    34                     inq[e.v]=1;
    35                     q.push(e.v);
    36                 }
    37             }
    38         }
    39     }
    40 }
    41 int main(){
    42     n=read(),m=read(),sta=read();
    43     int u,v,w;
    44     for(int i=1;i<=m;i++){
    45         u=read(),v=read(),w=read();
    46         add(u,v,w);
    47     }
    48     spfa(sta);
    49     for(int i=1;i<=n;i++){
    50         if(d[i]==-1) printf("2147483647 ");
    51         else printf("%d ",d[i]);
    52     }
    53     return 0;
    54 }

    前向星版:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<queue>
     6 #include<vector>
     7 #define maxn 10005
     8 #define maxm 500005
     9 using namespace std;
    10 int n,m,sta,last[maxn],cnt,inq[maxn],d[maxn];
    11 int read(){
    12     int x=0,f=1;char ch=getchar();
    13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    14     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 struct edge{int to,next,cost;}e[maxm];
    18 void add(int x,int y,int z){e[++cnt].to=y;e[cnt].next=last[x];last[x]=cnt;e[cnt].cost=z;}
    19 void spfa(int sta){
    20     memset(d,-1,sizeof(d)); d[sta]=0;
    21     memset(inq,0,sizeof(inq));
    22     queue<int> q;
    23     q.push(sta);
    24     while(!q.empty()){
    25         int k=q.front(); q.pop();
    26         inq[k]=0;
    27         for(int i=last[k];i;i=e[i].next){
    28             int v=e[i].to;
    29             if(d[v]==-1||d[v]>d[k]+e[i].cost){
    30                 d[v]=d[k]+e[i].cost;
    31                 if(!inq[v]){
    32                     inq[v]=1;
    33                     q.push(v);
    34                 }
    35             }
    36         }
    37     }
    38 }
    39 int main(){
    40     n=read(),m=read(),sta=read();
    41     int u,v,w;
    42     for(int i=1;i<=m;i++){
    43         u=read(),v=read(),w=read();
    44         add(u,v,w);
    45     }
    46     spfa(sta);
    47     for(int i=1;i<=n;i++){
    48         if(d[i]==-1) printf("2147483647 ");
    49         else printf("%d ",d[i]);
    50     }
    51     return 0;
    52 }
  • 相关阅读:
    Jzoj4822 完美标号
    Jzoj4822 完美标号
    Jzoj4792 整除
    Jzoj4792 整除
    Educational Codeforces Round 79 A. New Year Garland
    Good Bye 2019 C. Make Good
    ?Good Bye 2019 B. Interesting Subarray
    Good Bye 2019 A. Card Game
    力扣算法题—088扰乱字符串【二叉树】
    力扣算法题—086分隔链表
  • 原文地址:https://www.cnblogs.com/Emine/p/7596667.html
Copyright © 2011-2022 走看看