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)
 
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 }