首页 > 代码库 > 题目1008:最短路径问题

题目1008:最短路径问题

题目描述:
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
输入:
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
输出:
输出 一行有两个数, 最短距离及其花费。
样例输入:
3 21 2 5 62 3 4 51 30 0
样例输出:
9 11

---------------------------------------------------------------------

贴个别人用邻接表的代码:

  1 //邻接表+dijk算法  2   3 #include <iostream>  4 #include <cstdio>  5 #include <cstring>  6   7 using namespace std;  8   9 #define inf 10000000 10 const int Maxn = 200005; 11 int N,M; 12 struct Edge{ 13         int v,next; 14         int dt,ct; 15 }edge[Maxn];//边数 16 int first[1005]; 17 int r,s,t; 18 int vis[1005]; 19 struct BNode{ 20         int dist,cost; 21 }P[1005];      //节点信息 22  23 //相当于链表的头插发,很有意思。比用邻接矩阵高效多了 24 void addedge(int u, int v, int d, int p) 25 { 26         edge[r].next = first[u]; 27         edge[r].v = v; 28         edge[r].dt = d; 29         edge[r].ct = p; 30         first[u] = r; 31         r++; 32 } 33  34 int findminode()//在那么多节点中找最小的 35 { 36         int i,Maxn = inf; 37         int index = 0; 38         for(i = 1; i<=N; i++) 39         if(P[i].dist<Maxn && !vis[i]) 40         { 41                 Maxn = P[i].dist; 42                 index = i; 43         } 44         //注意,如果存在多个相同的最短路径,要返回最小花费的节点 45         if(index) 46         { 47                 for(i = 1; i<=N; i++) 48                 if(P[i].cost<P[index].cost && !vis[i])index = i; 49         } 50         return index; 51 } 52  53 void solve() 54 { 55         int i; 56         for(i = 1; i<=N; i++) 57                 P[i].dist = P[i].cost = inf; 58         P[s].dist = P[s].cost = 0; 59         memset(vis,0,sizeof(vis)); 60         int index = 1; 61         while(index<N)//更新N-1次就够了 62         { 63                 int x = findminode(); 64                 if(!x)break; 65                 vis[x] = 1; index++; 66                 for(i = first[x]; i!=-1; i = edge[i].next) 67                 { 68                         int v = edge[i].v; 69                         if(P[x].dist+edge[i].dt<P[v].dist && !vis[v])//更新节点 70                         { 71                                 P[v].dist = P[x].dist+edge[i].dt; 72                                 P[v].cost = P[x].cost+edge[i].ct; 73                         } 74                         else if(P[x].dist+edge[i].dt == P[v].dist && !vis[v])//如果存在多条最短路径,更新最小花费节点 75                         { 76                                 if(P[x].cost+edge[i].ct<P[v].cost)P[v].cost = P[x].cost+edge[i].ct; 77                         } 78                 } 79         } 80         cout<<P[t].dist<< <<P[t].cost<<endl; 81 } 82  83 int main() 84 { 85         int i,u,v,d,p; 86         while(scanf("%d%d",&N,&M)!=EOF) 87         { 88                 if(N == 0 && M == 0)break; 89                 memset(first,-1,sizeof(first)); 90                 r = 0; 91                 for(i = 0; i<M; i++) 92                 { 93                         scanf("%d%d%d%d",&u,&v,&d,&p); 94                         addedge(u,v,d,p); 95                         addedge(v,u,d,p); 96                 } 97                 scanf("%d%d",&s,&t); 98                 solve(); 99         }100         return 0;101 }

自己的代码,但是stack overflow了~原因应该是递归太深,导致占用堆栈过多。。

  1 #include<stdio.h>  2 #define M 10000  3 #define N 1000  4 #include<stdlib.h>  5 struct L{  6     int a,b,d,p;  7 }l0[M];  8 void search(int n0,int d0,int p0,int s0,struct L q0);  9 int x; 10 int o[M][2];//存长度和花费 11 int m,n; 12 int s,t; 13 int main(int argc, char const *argv[]) 14 { 15     int n0,d0,p0; 16     int i; 17     int min; 18     struct L q0;//存上一条边信息 19     scanf("%d %d",&n,&m); 20     while(m!=0&&n!=0) 21     { 22         for(i=0;i<m;i++) 23             scanf("%d %d %d %d",&l0[i].a,&l0[i].b,&l0[i].d,&l0[i].p); 24         scanf("%d %d",&s,&t); 25     //    printf("---1---\n"); 26         x=0; 27         q0.a=0;q0.b=0;q0.d=0;q0.p=0; 28         d0=0; 29         p0=0; 30         n0=1; 31     //    printf("---2---\n"); 32         search(n0,d0,p0,s,q0); 33     //    printf("---3---\n"); 34         min=0; 35         for(i=1;i<x;i++) 36             if((o[min][0]==o[i][0]&&o[min][1]>o[i][1])||o[min][0]>o[i][0]) 37                     min=i; 38         printf("%d %d\n",o[min][0],o[min][1]); 39     //    printf("---4---\n"); 40         scanf("%d %d",&n,&m); 41     } 42     return 0; 43 } 44 void search(int n0,int d0,int p0,int s0,struct L q0) 45 { 46     int i,count1,count2; 47     struct L *l1,*l2; 48     l1=(struct L*)malloc(sizeof(struct L)*100); 49     l2=(struct L*)malloc(sizeof(struct L)*100); 50 //    printf("search\n");// 51     count1=count2=0; 52 //            printf("%d\n",n0);// 53     n0++; 54     for(i=0;i<m;i++) 55     { 56         if(l0[i].a!=q0.a||l0[i].b!=q0.b||l0[i].d!=q0.d||l0[i].p!=q0.p) 57         { 58             if(l0[i].a==s0) 59             { 60                 l1[count1]=l0[i]; 61                 count1++; 62             } 63             else if(l0[i].b==s0) 64             { 65                 l2[count2]=l0[i]; 66                 count2++; 67             } 68         } 69     } 70     if(count1==0) 71         free(l1); 72     else 73     { 74         for(i=0;i<count1;i++) 75         { 76             if(l1[i].b==t&&n0==n) 77             { 78  79                 o[x][0]=d0+l1[i].d; 80                 o[x][1]=p0+l1[i].p; 81                 x++; 82             } 83             else 84             { 85                 q0=l1[i]; 86                 d0=d0+l1[i].d; 87                 p0=p0+l1[i].p; 88                 s0=l1[i].b; 89                 search(n0,d0,p0,s0,q0); 90             } 91         } 92  93     free(l1); 94     } 95     if(count2==0) 96         free(l1); 97     else 98     { 99         for(i=0;i<count2;i++)100         {101             if(l2[i].a==t&&n0==n)102             {103                 o[x][0]=d0+l2[i].d;104                 o[x][1]=p0+l2[i].p;105                 x++;106             }107             else108             {109                 q0=l2[i];110                 d0=d0+l2[i].d;111                 p0=p0+l2[i].p;112                 s0=l2[i].a;113                 search(n0,d0,p0,s0,q0);114             }115         }116         free(l2);117     }118 }

数据结构这块还是没掌握好~