hdu 3790 最短路径问题(迪杰斯特拉) 最短路径问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 20555 Accepted Submission(s):
6098
Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数
a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数
s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
(1<n<=1000, 0<m<100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
Sample Output
9 11
Source
Recommend
notonlysuccess | We have carefully selected several
similar problems for you: 1142 2680 1385 1598 1596
同样是最短路的模板题,不过加入了花费这个元素,当路程相同时,选择花费小的方案,还是比较好处理的。
题意:中文题,很好理解。
附上代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define M 1005 5 #define MAX 0x3f3f3f3f 6 using namespace std; 7 int map[M][M],vis[M],dis[M],money[M][M],r[M]; 8 int main() 9 { 10 int n,m,i,j,s,t; 11 while(~scanf("%d%d",&n,&m)) 12 { 13 if(!n&&!m) break; 14 memset(vis,0,sizeof(vis)); 15 memset(dis,0,sizeof(dis)); 16 memset(r,0,sizeof(r)); 17 for(i=1; i<=n; i++) 18 for(j=1; j<=n; j++) 19 { 20 if(i==j) map[i][j]=0,money[i][j]=0; 21 else map[i][j]=MAX,money[i][j]=MAX; 22 } 23 int a,b,c,d; 24 while(m--) 25 { 26 scanf("%d%d%d%d",&a,&b,&c,&d); 27 if(map[a][b]>c) 28 { 29 map[a][b]=c,map[b][a]=c; 30 money[a][b]=d,money[b][a]=d; 31 } 32 } 33 scanf("%d%d",&s,&t); 34 vis[s]=1; 35 for(i=1; i<=n; i++) 36 { 37 dis[i]=map[s][i]; 38 r[i]=money[s][i]; 39 } 40 int w,min; 41 for(i=1; i<=n; i++) 42 { 43 min=MAX; 44 for(j=1; j<=n; j++) 45 if(!vis[j]&&min>dis[j]) 46 { 47 min=dis[j]; 48 w=j; 49 } 50 vis[w]=1; 51 for(j=1; j<=n; j++) 52 { 53 if(!vis[j]&&map[w][j]<MAX) 54 { 55 if(dis[j]>dis[w]+map[w][j]) 56 { 57 dis[j]=dis[w]+map[w][j]; 58 r[j]=r[w]+money[w][j]; 59 } 60 else if(dis[j]==dis[w]+map[w][j] && r[j]>r[w]+money[w][j]) //路程相同时,花费的处理 61 r[j]=r[w]+money[w][j]; 62 } 63 } 64 } 65 printf("%d %d ",dis[t],r[t]); 66 } 67 return 0; 68 }
邻接表:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #define M 1005 6 #define N 100005 7 #define INF 0x3f3f3f3f 8 #define ll long long 9 using namespace std; 10 int n,m,s,t,tol; 11 struct Edge 12 { 13 int from,to,val,p; 14 int next; 15 } edge[N*2]; 16 int head[N*2],dis[M],r[M]; 17 bool vis[M]; 18 19 void init() 20 { 21 tol=0; 22 memset(head,-1,sizeof(head)); 23 } 24 25 void addEdge(int u,int v,int val,int p) 26 { 27 edge[tol].from=u; 28 edge[tol].to=v; 29 edge[tol].val=val; 30 edge[tol].p=p; 31 edge[tol].next=head[u]; 32 head[u]=tol++; 33 edge[tol].from=v; 34 edge[tol].to=u; 35 edge[tol].val=val; 36 edge[tol].p=p; 37 edge[tol].next=head[v]; 38 head[v]=tol++; 39 } 40 41 void getmap() 42 { 43 int i,j; 44 int a,b,c,d; 45 while(m--) 46 { 47 scanf("%d%d%d%d",&a,&b,&c,&d); 48 addEdge(a,b,c,d); 49 } 50 scanf("%d%d",&s,&t); 51 memset(dis,INF,sizeof(dis)); 52 memset(r,INF,sizeof(r)); 53 memset(vis,false,sizeof(vis)); 54 } 55 56 void spfa() 57 { 58 queue<int>q; 59 q.push(s); 60 dis[s]=0; 61 r[s]=0; 62 vis[s]=true; 63 while(!q.empty()) 64 { 65 int u=q.front(); 66 q.pop(); 67 vis[u]=false; 68 for(int i=head[u]; i!=-1; i=edge[i].next) 69 { 70 int v=edge[i].to; 71 if(dis[v]>dis[u]+edge[i].val) 72 { 73 dis[v]=dis[u]+edge[i].val; 74 r[v]=r[u]+edge[i].p; 75 if(!vis[v]) 76 { 77 vis[v]=true; 78 q.push(v); 79 } 80 } 81 else if(dis[v]==dis[u]+edge[i].val) 82 { 83 if(r[v]>r[u]+edge[i].p) 84 { 85 r[v]=r[u]+edge[i].p; 86 if(!vis[v]) 87 { 88 vis[v]=true; 89 q.push(v); 90 } 91 } 92 } 93 } 94 } 95 printf("%d %d ",dis[t],r[t]); 96 return; 97 } 98 99 int main() 100 { 101 while(~scanf("%d%d",&n,&m)) 102 { 103 if(n==0&&m==0) break; 104 init(); 105 getmap(); 106 spfa(); 107 } 108 return 0; 109 }