hdu 1874(最短路 Dilkstra +优先队列优化+spfa)
畅通工程续
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 50537 Accepted Submission(s): 18852
Problem Description
某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
Input
本题目包含多组数据,请处理到文件结束。
每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
Output
对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.
Sample Input
3 3
0 1 1
0 2 3
1 2 1
0 2
3 1
0 1 1
1 2
Sample Output
2
-1
Author
linle
Source
1》Dijkstra算法求最短路
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<queue> #include<map> #include<set> #include<vector> #include<cstdlib> #include<string> #define eps 0.000000001 typedef long long ll; typedef unsigned long long LL; using namespace std; const int N=300+10; const int INF=0x3f3f3f3f; int n,m; int mp[N][N]; int vis[N]; int dis[N]; void init(){ // memset(dis,0,sizeof(dis)); memset(vis,0,sizeof(vis)); for(int i=0;i<N;i++) for(int j=0;j<N;j++){mp[i][j]=INF; } } void Dijkstra(int v,int e){ dis[v]=0; vis[v]=1; int pos; for(int i=0;i<n;i++)dis[i]=mp[v][i]; for(int i=1;i<n;i++){ int minn=INF; for(int j=0;j<n;j++){ if(dis[j]<minn&&vis[j]==0){ pos=j; minn=dis[j]; } } vis[pos]=1; for(int j=0;j<n;j++){ if(dis[pos]+mp[pos][j]<dis[j]&&vis[j]==0) dis[j]=dis[pos]+mp[pos][j]; } } } int main(){ while(scanf("%d%d",&n,&m)!=EOF){ init(); for(int i=0;i<m;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); if(z<mp[x][y]) mp[x][y]=mp[y][x]=z; } int v0,v; scanf("%d%d",&v0,&v); if(v0==v){ cout<<0<<endl; continue; } Dijkstra(v0,v); if(dis[v]==INF)cout<<-1<<endl; else cout<<dis[v]<<endl; } }
Dijkstra +优先队列优化
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<queue> 7 #include<map> 8 #include<stack> 9 #include<set> 10 #include<vector> 11 #include<cstdlib> 12 #include<string> 13 #define eps 0.000000001 14 typedef long long ll; 15 typedef unsigned long long LL; 16 using namespace std; 17 const int N=1000+10; 18 const int INF=0x3f3f3f3f; 19 int m,n; 20 struct node{ 21 int to,next,w; 22 bool operator<(const node &a)const{ 23 return w>a.w; 24 } 25 }edge[N]; 26 int head[N]; 27 int t; 28 int vis[N],dis[N]; 29 void init(){ 30 memset(vis,0,sizeof(vis)); 31 t=0; 32 memset(head,-1,sizeof(head)); 33 for(int i=0;i<N;i++)dis[i]=INF; 34 } 35 void add(int u,int v,int w){ 36 edge[t].to=v; 37 edge[t].w=w; 38 edge[t].next=head[u]; 39 head[u]=t++; 40 } 41 int Dijkstra(int x){ 42 dis[x]=0; 43 node t1,t2; 44 priority_queue<node>q; 45 t1.to=x; 46 q.push(t1); 47 while(!q.empty()){ 48 t1=q.top(); 49 q.pop(); 50 int u=t1.to; 51 if(vis[u]==1)continue; 52 vis[u]=1; 53 for(int i=head[u];i!=-1;i=edge[i].next){ 54 int v=edge[i].to; 55 if(vis[v]==0&&dis[v]>dis[u]+edge[i].w){ 56 dis[v]=dis[u]+edge[i].w; 57 t2.to=v; 58 t2.w=dis[v]; 59 q.push(t2); 60 } 61 } 62 } 63 64 } 65 int main(){ 66 while(scanf("%d%d",&n,&m)!=EOF){ 67 init(); 68 for(int i=0;i<m;i++){ 69 int u,v,w; 70 scanf("%d%d%d",&u,&v,&w); 71 add(u,v,w); 72 add(v,u,w); 73 } 74 int x,y; 75 scanf("%d%d",&x,&y); 76 Dijkstra(x); 77 if(dis[y]==INF)cout<<-1<<endl; 78 else 79 cout<<dis[y]<<endl; 80 81 } 82 }
spfa算法求最短路
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdlib> 6 #include<string.h> 7 #include<set> 8 #include<vector> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<cmath> 13 typedef long long ll; 14 typedef unsigned long long LL; 15 using namespace std; 16 const double PI=acos(-1.0); 17 const double eps=0.0000000001; 18 const int INF=0x3f3f3f3f; 19 const int N=100000+10; 20 int n,m; 21 struct node{ 22 int w,next,to; 23 }edge[N<<1]; 24 int head[N]; 25 int tot; 26 void init(){ 27 memset(head,-1,sizeof(head)); 28 tot=0; 29 } 30 void add(int u,int v,int w){ 31 edge[tot].to=v; 32 edge[tot].w=w; 33 edge[tot].next=head[u]; 34 head[u]=tot++; 35 } 36 int dis[N]; 37 int vis[N]; 38 void spfa(int s){ 39 queue<int>q; 40 memset(dis,INF,sizeof(dis)); 41 dis[s]=0; 42 memset(vis,0,sizeof(vis)); 43 q.push(s); 44 vis[s]=1; 45 while(!q.empty()){ 46 int x=q.front(); 47 q.pop(); 48 vis[x]=0; 49 for(int i=head[x];i!=-1;i=edge[i].next){ 50 int v=edge[i].to; 51 if(dis[x]+edge[i].w<dis[v]){ 52 dis[v]=dis[x]+edge[i].w; 53 if(vis[v])continue; 54 vis[v]=1; 55 q.push(v); 56 } 57 58 } 59 } 60 } 61 int main(){ 62 while(cin>>n>>m){ 63 init(); 64 for(int i=0;i<m;i++){ 65 int u,v,w; 66 scanf("%d%d%d",&u,&v,&w); 67 add(u,v,w); 68 add(v,u,w); 69 } 70 int u,v; 71 scanf("%d%d",&u,&v); 72 spfa(u); 73 if(dis[v]==INF)cout<<-1<<endl; 74 else{ 75 cout<<dis[v]<<endl; 76 } 77 } 78 }