hdu 3790 最短路径问题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790
题意就不说了 相信都可以看懂,和一般的最短路唯一的不同之处就是加了一个费用限制,在最短路相同时要保证费用最小,所以要增加两个数组分别记录各边之间的费用,和到各点的最小费用,
在选择点和更新时要注意 在路相同时要对费用进行判断看是否有必要更新费用。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 using namespace std; 6 const int MAX=1020; 7 const int INF=12345678; 8 int map[MAX][MAX]; 9 int cost[MAX][MAX]; 10 int vist[MAX],dist[MAX]; 11 int pay[MAX]; 12 int n,m; 13 14 void init() 15 { 16 int i,j; 17 memset(vist,0,sizeof(vist)); 18 19 for(i=1;i<=n;i++) 20 { 21 for(j=1;j<=n;j++) 22 { 23 map[i][j]=INF; 24 cost[i][j]=INF; 25 } 26 map[i][i]=0; 27 dist[i]=INF; 28 pay[i]=INF; 29 cost[i][i]=0; 30 } 31 } 32 void Dij(int s) 33 { 34 int i,j,v,min,money; 35 for(i=1;i<=n;i++) 36 { 37 dist[i]=map[s][i]; 38 pay[i]=cost[s][i]; 39 } 40 dist[s]=0; 41 vist[s]=1; 42 pay[s]=0; 43 v=s; 44 for(i=1;i<n;i++) 45 { 46 min=INF; 47 money=INF; 48 for(j=1;j<=n;j++) 49 { 50 if(!vist[j]&&dist[j]<min) 51 { 52 min=dist[j]; 53 money=pay[j]; 54 v=j; 55 } 56 else if (!vist[j]&&dist[j]==min&&pay[j]<money) 57 { 58 money=pay[j]; 59 v=j; 60 } 61 } 62 vist[v]=1; 63 for(j=1;j<=n;j++) 64 { 65 if(!vist[j]&&(dist[j]>dist[v]+map[v][j])) 66 { 67 dist[j]=dist[v]+map[v][j]; 68 pay[j]=pay[v]+cost[v][j]; 69 } 70 else if(!vist[j]&&(dist[j]==dist[v]+map[v][j])&&(pay[j]>pay[v]+cost[v][j])) 71 pay[j]=pay[v]+cost[v][j]; 72 } 73 74 } 75 } 76 77 int main() 78 { 79 int i,x,y,p,q,s,t; 80 while(scanf("%d%d",&n,&m),n+m) 81 { 82 init(); 83 for(i=1;i<=m;i++) 84 { 85 scanf("%d%d%d%d",&x,&y,&p,&q); 86 if(map[x][y]>p||(map[x][y]==p&&cost[x][y]>q)) 87 { 88 map[x][y]=map[y][x]=p; 89 cost[x][y]=cost[y][x]=q; 90 } 91 } 92 scanf("%d%d",&s,&t); 93 Dij(s); 94 printf("%d %d\n",dist[t],pay[t]); 95 } 96 return 0; 97 }