题目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 2
1 2 5 6
2 3 4 5
1 3
0 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             else
108             {
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 }

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

题目1008:最短路径问题

时间: 2024-08-25 06:38:20

题目1008:最短路径问题的相关文章

九度1008,最短路径问题

题目1008:最短路径问题 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5119 解决:1631 题目描述: 给你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<

hiho一下 第二十三周---题目1 : 最短路径&#183;一

题目1 : 最短路径·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 万圣节的早上,小Hi和小Ho在经历了一个小时的争论后,终于决定了如何度过这样有意义的一天--他们决定去闯鬼屋! 在鬼屋门口排上了若干小时的队伍之后,刚刚进入鬼屋的小Hi和小Ho都颇饥饿,于是他们决定利用进门前领到的地图,找到一条通往终点的最短路径. 鬼屋中一共有N个地点,分别编号为1..N,这N个地点之间互相有一些道路连通,两个地点之间可能有多条道路连通,但是并不存在一条两端都是同一个地点的道

题目1008:最短路径问题(SPFA算法)

题目链接:http://ac.jobdu.com/problem.php?pid=1008 详解连接:https://github.com/Pacsiy/JobDu 最短路径四种算法详解链接:http://blog.csdn.net/hjd_love_zzt/article/details/26739593 参考代码: // // Created by AlvinZH on 2017/4/29. // Copyright (c) AlvinZH. All rights reserved. //

九度 题目1008:最短路径问题

最短路径问题,首先想到了贪心算法实现的dijkstra算法:这道题我用了链表的存储方式,其实用邻接矩阵也可以,主要为了练手,并且链表比矩阵要节约空间: 题目描述: 给你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时输入结

九度OJ刷题——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 2

#HDU 3790 最短路径问题 【Dijkstra入门题】

题目: 最短路径问题 Time Limit: 2000/1000 MS (Java/Others)????Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 19767????Accepted Submission(s): 5880 Problem Description 给你n个点.m条无向边,每条边都有长度d和花费p.给你起点s终点t,要求输出起点到终点的最短距离及其花费,假设最短距离有多条路线,则输出花费最少的. ?

昂贵的聘礼 poj 1062 Dijkstra

中文题,题意就不多说了,讲讲思路吧,先根据题意构图,与普通最短路不同的是这一题加了一个Rank,每个点都有一个Rank,题目要求最短路径上的点的Rank的最大差值在 M范围内,Dijkstra判断条件时加上Rank约束就行了.我没有添加汇点直接写的,另贴上别人添加汇点的写法. 我的代码: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include

1491: [NOI2007]社交网络

1491: [NOI2007]社交网络 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 881  Solved: 518[Submit][Status] Description Input Output 输出文件包括n 行,每行一个实数,精确到小数点后3 位.第i 行的实数表 示结点i 在社交网络中的重要程度. Sample Input 4 4 1 2 1 2 3 1 3 4 1 4 1 1 Sample Output 1.000 1.000 1.0

洛谷P1613 跑路

P1613 跑路 题目描述 小A的工作不仅繁琐,更有苛刻的规定,要求小A每天早上在6:00之前到达公司,否则这个月工资清零.可是小A偏偏又有赖床的坏毛病.于是为了保住自己的工资,小A买了一个十分牛B的空间跑路器,每秒钟可以跑2^k千米(k是任意自然数).当然,这个机器是用longint存的,所以总跑路长度不能超过maxlongint千米.小A的家到公司的路可以看做一个有向图,小A家为点1,公司为点n,每条边长度均为一千米.小A想每天能醒地尽量晚,所以让你帮他算算,他最少需要几秒才能到公司.数据保