最短路问题;
坑点1:是先输入边,再输入点;
坑点2:数据很大,不适合用别的模板;
坑点3:有重边 需要判定;
题意:题目大意:有N个点,给出从a点到b点的距离,当然a和b是互相可以抵达的,问从1到n的最短距离
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
AC代码:
解法一:(dijkstra算法)(PS:2016.3.22修改自己写的版本)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define MAX 9999999 using namespace std ; int u , v ,n, dis[1111],vis[1111],ma[1111][1111]; void dijk() { int k , mini; for(int i = 1 ; i <=v;i++) { dis[i]=ma[1][i]; } for(int i = 1 ;i<=v;i++) { mini=MAX; for(int j = 1 ; j<=v;j++) { if(!vis[j]&&dis[j]<mini) { mini=dis[j]; k=j; } } vis[k]=1; for(int j=1 ;j<=v;j++) { if(dis[j]>dis[k]+ma[k][j]) { dis[j]=dis[k]+ma[k][j]; } } } } int main() { while(cin>>u>>v) { n=0; for(int i = 0 ; i <=v;i++) { for(int j = 0 ; j <=v;j++) { ma[i][j]=MAX; } ma[i][i]=0; vis[i]=0; dis[i]=MAX; } for(int i = 1 ;i<=u;i++) { int a , b , len; cin>>a>>b>>len; n=max(max(n,a),b); if(ma[a][b]>len) { ma[a][b]=ma[b][a]=len; } } dijk(); printf("%d\n",dis[v]); } return 0 ; }
解法二(Bellman-Ford)
//*bellman算法: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define N 2010 #define MAX 99999999 using namespace std ; struct node{ int a , b , w ; }edge[N]; int n , m ; void bell() { int i , j ; int d[N]; for(int i =1 ; i<=n;i++)//*距离初始化为无穷; { d[i]=MAX; } d[1]=0;//*初始地点为0; for(i=1;i<=n;i++) { for(j=1;j<=m;j++)//*按点-边搜,顺便解决了重边问题; { if(d[edge[j].a]>d[edge[j].b]+edge[j].w) d[edge[j].a]= d[edge[j].b]+edge[j].w; if(d[edge[j].b]>d[edge[j].a]+edge[j].w) d[edge[j].b]= d[edge[j].a]+edge[j].w; } } printf("%d\n",d[n]); } int main() { int i , a , b ,c; while(cin>>m>>n) { for(int i =1 ; i<=m;i++)//*结构体存边和权 { cin>>a>>b>>c; edge[i].a=a; edge[i].b=b; edge[i].w=c; } bell(); } return 0 ; }
方法三(Floyd-Warshall):虽然过不去数据,因为太大;但是值得一试;
#include <iostream> #include <stdio.h> #include <math.h> #include <algorithm> #include <cstring> #define N 2000 #define MAX 99999999 using namespace std ; int u , v ; int dis[N][N]; void warsh() { int i , j , k ; for(k=1; k<=v; k++) { for(i=1; i<=v; i++) { for(j=1; j<=v; j++) { dis[i][j]=min(dis[i][j],dis[k][j]+dis[i][k]); } } } } int main() { cin>>u>>v ; int a, b , c ; for(int i = 1 ; i <= v ; i++) { for(int j = 1 ; j <=v; j++) { dis[i][j]=MAX; } } for(int i = 0 ; i < v ; i++) { dis[i][i]=0; } for(int i = 1 ; i <=u ; i++) { cin>>a>>b>>c; dis[a][b]=dis[b][a]=c; } warsh(); cout<<dis[1][v]<<endl; return 0 ; }