洛谷 P3371 【模板】单源最短路径
2017-10-17 20:29
387 查看
题目描述
如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。输入输出格式
输入格式:
第一行包含三个整数N、M、S,分别表示点的个数、有向边的个数4000
、出发点的编号。
接下来 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
样例说明:
solution
40%的数据,Floyd模板题70%的数据,dijkstra模板题
100%的数据,spfa/堆优化的dijkstra模板题
code
当然是四种算法都有啦!#include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; template<typename T> void input(T &x) { x=0; T a=1; register char c=getchar(); for(;c<'0'||c>'9';c=getchar()) if(c=='-') a=-1; for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0'; x*=a; return; } namespace __Floyd { const int MAXN=110; const int inf=2147483647; int dis[MAXN][MAXN]; void Floyd(int n,int m,int s) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i][j]=inf*(i!=j); for(int i=1;i<=m;i++) { int u,v,w; input(u),input(v),input(w); if(w<dis[u][v]) dis[u][v]=w; } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j&&i!=k&&j!=k&&dis[i][k]!=inf&&dis[k][j]!=inf) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); for(int i=1;i<=n;i++) printf("%d ",dis[s][i]); return; } } namespace __dijkstra { const int MAXN=1010; const int inf=2147483647; int G[MAXN][MAXN]; int dis[MAXN]; bool vis[MAXN]; void dijkstra(int n,int m,int s) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) G[i][j]=inf*(i!=j); for(int i=1;i<=m;i++) { int u,v,w; input(u),input(v),input(w); if(w<G[u][v]) G[u][v]=w; } for(int i=1;i<=n;i++) dis[i]=G[s][i],vis[i]=false; vis[s]=true; for(int k=1;k<n;k++) { int Min=inf,u=-1; for(int i=1;i<=n;i++) if(!vis[i]&&dis[i]<Min) Min=dis[u=i]; if(u==-1) break; vis[u]=true; for(int v=1;v<=n;v++) if(G[u][v]<inf&&dis[u]+G[u][v]<dis[v]) dis[v]=dis[u]+G[u][v]; } for(int i=1;i<=n;i++) printf("%d ",dis[i]); return; } } namespace __spfa { const int MAXN=10010; const int MAXM=500010; const int inf=2147483647; struct Edge { int u,v,w,next; Edge(int u=0,int v=0,int w=0,int next=0): u(u),v(v),w(w),next(next) {} }; Edge edge[MAXM]; int head[MAXN],cnt; void addedge(int u,int v,int w) { edge[++cnt]=Edge(u,v,w,head[u]); head[u]=cnt; return; } queue<int> q; bool inq[MAXN]; int dis[MAXN]; void spfa(int n,int m,int s) { for(int i=1;i<=m;i++) { int u,v,w; input(u),input(v),input(w); addedge(u,v,w); } for(int i=1;i<=n;i++) dis[i]=inf,inq[i]=false; q.push(s); inq[s]=true; dis[s]=0; while(!q.empty()) { int u=q.front(); q.pop(); inq[u]=false; for(int i=head[u];i;i=edge[i].next) { int v=edge[i].v; if(dis[u]+edge[i].w<dis[v]) { dis[v]=dis[u]+edge[i].w; if(!inq[v]) { q.push(v); inq[v]=true; } } } } for(int i=1;i<=n;i++) printf("%d ",dis[i]); return; } } namespace __dijkstra_heap { const int MAXN=10010; const int MAXM=500010; const int inf=2147483647; struct Edge { int u,v,w,next; Edge(int u=0,int v=0,int w=0,int next=0): u(u),v(v),w(w),next(next) {} }; Edge edge[MAXM]; int head[MAXN],cnt; void addedge(int u,int v,int w) { edge[++cnt]=Edge(u,v,w,head[u]); head[u]=cnt; return; } struct Data { int dis,x; Data(int dis=0,int x=0): dis(dis),x(x) {} bool operator < (const Data &q)const { return dis<q.dis; } bool operator > (const Data &q)const { return dis>q.dis; } }; priority_queue<Data,vector<Data>,greater<Data> > heap; int dis[MAXN]; bool vis[MAXN]; void dijkstra(int n,int m,int s) { for(int i=1;i<=m;i++) { int u,v,w; input(u),input(v),input(w); addedge(u,v,w); } for(int i=1;i<=n;i++) dis[i]=inf,vis[i]=false; dis[s]=0; heap.push(Data(dis[s],s)); while(!heap.empty()) { Data now=heap.top(); heap.pop(); int u=now.x; if(vis[u]) continue; vis[u]=true; for(int i=head[u];i;i=edge[i].next) { int v=edge[i].v; if(dis[u]+edge[i].w<dis[v]) { dis[v]=dis[u]+edge[i].w; heap.push(Data(dis[v],v)); } } } for(int i=1;i<=n;i++) printf("%d ",dis[i]); return; } } int main() { int n,m,s; input(n),input(m),input(s); if(n<=100) __Floyd::Floyd(n,m,s); else if(n<=1000) __dijkstra::dijkstra(n,m,s); else if(m<=10000) __spfa::spfa(n,m,s); else __dijkstra_heap::dijkstra(n,m,s); puts(""); return 0; }
相关文章推荐
- P3371 单源最短路径【模板】 洛谷
- 洛谷 P3371 【模板】单源最短路径
- 洛谷 P3371 【模板】单源最短路径(Dijkstra + 堆优化)
- 洛谷 P3371 【模板】单源最短路径
- 洛谷 P3371 【模板】单源最短路径
- [洛谷]P3371 单源最短路径模板 SPFA
- 洛谷 P3371 【模板】单源最短路径
- [洛谷]P3371 单源最短路径模板-bell
- [洛谷]P3371 单源最短路径模板 Dijkstra
- 洛谷 P3371 [模版] 单源最短路径
- P3371 【模板】单源最短路径 SPFA优化 dijkstra堆优化
- [洛谷3371]【模板】单源最短路径
- P3371 【模板】单源最短路径
- P3371 【模板】单源最短路径
- P3371 【模板】单源最短路径
- P3371 【模板】单源最短路径
- 洛谷_3371 单源最短路径
- Dijkstra模板求单源点最短路径
- hdu1874 畅通工程续 单源最短路径 模板题
- [模板] 单源最短路径