首页  »   C++

【luogu 3371】【模板】单流最短路径

网友分享于:2013-11-02  浏览:0次
【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 }

相关解决方案

最新解决方案