Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 40039 | Accepted: 13620 |
Description
Input
Output
Sample Input
5 5 1 2 20 2 3 30 3 4 20 4 5 20 1 5 100
Sample Output
90
Hint
Source
有N个点,给出从a点到b点的距离,当然a和b是互相可以抵达的,问从1到n的最短距离。
①Dijkstra;
②使用STL的priority_queue实现。
①
/* * Copyright (c) 2016, 烟台大学计算机与控制工程学院 * All rights reserved. * 文件名称:dijkstra.cpp * 作 者:单昕昕 * 完成日期:2016年3月30日 * 版 本 号:v1.0 */ #include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> #define MAXN 1010 #define INF 0xfffffff//0X代表16进制,后面是数字,十进制是4294967295 using namespace std; int cost[MAXN][MAXN],dis[MAXN],n,t; bool used[MAXN];//标识是否使用过 void dijkstra(int s) { memset(used,0,sizeof(used)); fill(dis,dis+n+1,INF); fill(used,used+n+1,false); dis[s]=0; while(true) { int v=-1; //从未使用过的顶点中选择一个距离最小的顶点 for(int u=0; u<n; ++u) if(!used[u]&&(v==-1||dis[u]<dis[v])) v=u; if(v==-1) break; used[v]=true; for(int u=0; u<=n; ++u) dis[u]=min(dis[u],dis[v]+cost[v][u]); } } int main() { int a,b,l; while(scanf("%d%d",&t,&n)!=EOF) { for(int i=0; i<=n; ++i) for(int j=0; j<=n; ++j) cost[i][j]=INF;//手动初始化,不能fill了…… for(int i=0; i<t; i++) { scanf("%d%d%d",&a,&b,&l); if(l<cost[a][b]) cost[a][b]=cost[b][a]=l;//无向图 } dijkstra(1); printf("%d\n",dis[n]); } return 0; } /* 5 5 1 2 20 2 3 30 3 4 20 4 5 20 1 5 100 */
②使用STL的priority_queue实现。
内存占用少:
/* * Copyright (c) 2016, 烟台大学计算机与控制工程学院 * All rights reserved. * 文件名称:queue.cpp * 作 者:单昕昕 * 完成日期:2016年6月1日 * 版 本 号:v2.0 */ #include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> #define INF 0xfffffff//0X代表16进制,后面是数字,十进制是4294967295 #define MAXN 1010 using namespace std; int dis[MAXN],n,t; struct edge { int to; int cost; }; vector<edge> G[MAXN];//边表 typedef pair<int,int> P; //first是最短距离,second是顶点的编号 void dijkstra(int s) { //通过指定greater<P>参数,堆按照first从大到小的顺序取初值 priority_queue<P,vector<P>,greater<P> > que; fill(dis,dis+n+1,INF);//初始化范围要到n dis[s]=0; que.push(P(0,s)); while(!que.empty()) { P p=que.top(); que.pop(); int v=p.second; if(dis[v]<p.first) continue; for(int i=0; i<G[v].size(); ++i) { edge e=G[v][i]; if(dis[e.to]>dis[v]+e.cost)//Dijkstra { dis[e.to]=dis[v]+e.cost; que.push(P(dis[e.to],e.to)); } } } } int main() { int a,b,l; while(scanf("%d%d",&t,&n)!=EOF) { for(int i=0; i<t; i++) { scanf("%d%d%d",&a,&b,&l);//a->b的距离是l G[a].push_back({b,l});//这里的语法要注意 G[b].push_back({a,l}); } dijkstra(1);//起点是1 printf("%d\n",dis[n]); } return 0; } /* 5 5 1 2 20 2 3 30 3 4 20 4 5 20 1 5 100 */
③
/* * Copyright (c) 2016, 烟台大学计算机与控制工程学院 * All rights reserved. * 文件名称:dijkstra.cpp * 作 者:单昕昕 * 完成日期:2016年3月30日 * 版 本 号:v1.0 */ #include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> #define inf 0xfffffff//0X代表16进制,后面是数字,十进制是4294967295 using namespace std; int p[1003][1003],flag[1003],dis[1003],mmin,n,t; void dijkstra() { memset(flag,0,sizeof(flag)); for(int i=2; i<=n; i++) { dis[i]=p[1][i]; } flag[1]=1; int pre; for(int i=1; i<=n; i++) { mmin=inf; for(int j=1; j<=n; j++) { if(flag[j]==0&&dis[j]<mmin) { mmin=dis[j]; pre=j; } } if(mmin==inf) break; flag[pre]=1; for(int j=1; j<=n; j++) //找最短路 { if(flag[j]==0&&dis[pre]+p[pre][j]<dis[j]) { dis[j]=dis[pre]+p[pre][j]; } } } } int main() { int a,b,l; while(scanf("%d%d",&t,&n)!=EOF) { for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { p[i][j]=inf; } } for(int i=0; i<t; i++) { scanf("%d%d%d",&a,&b,&l); if(l<p[a][b]) { p[a][b]=p[b][a]=l;//无向图 } } dijkstra(); printf("%d\n",dis[n]); } return 0; }