随笔 - 172,  文章 - 0,  评论 - 4,  阅读 - 55369
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

 

 

复制代码
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=1<<31-1;
 6 int map[1004][1004][2];
 7 int v[1004],s1[1004],s2[1004];
 8 int n;
 9 void dijk(int x)
10 {
11     v[x]=1;
12     int i;
13     for (i=1;i<=n;i++)
14     {
15         s1[i]=map[i][x][0];
16         s2[i]=map[i][x][1];
17     }
18     while (1)
19     {
20         int m1=N,m2=N,p=x;
21         for (i=1;i<=n;i++)
22         {
23             if (v[i]) continue;
24             if (m1>s1[i])
25             {
26                m1=s1[i];
27                m2=s2[i];
28                p=i;
29             }
30             else if (m1==s1[i]&&m2<s2[i])
31             {
32                 m2=s2[i];
33                 p=i;
34             }
35         }
36         if (p==x) break;
37         v[p]=1;
38         for (i=1;i<=n;i++)
39         {
40             if (v[i]) continue;
41             if (s1[i]>s1[p]+map[p][i][0])
42             {
43                 s1[i]=s1[p]+map[p][i][0];
44                 s2[i]=s2[p]+map[p][i][1];
45             }
46             else if (s1[i]==s1[p]+map[p][i][0]&&s2[i]>s2[p]+map[p][i][1])
47             s2[i]=s2[p]+map[p][i][1];
48         }
49     }
50 }
51 int main()
52 {
53     int m,i,j,a,b,c,d;
54     while (~scanf("%d%d",&n,&m))
55     {
56         if (n==0&&m==0) break;
57         for (i=1;i<=n;i++)
58         for (j=1;j<=n;j++)
59         {
60             map[i][j][0]=N;
61             map[i][j][1]=N;
62         }
63         for (i=1;i<=m;i++)
64         {
65             scanf("%d%d%d%d",&a,&b,&c,&d);
66             if (map[a][b][0]>c)
67             {
68                 map[a][b][0]=map[b][a][0]=c;
69                 map[a][b][1]=map[b][a][1]=d;
70             }
71             else if (map[a][b][0]==c&&map[a][b][0]>d)
72             {
73                 map[a][b][0]=map[b][a][0]=c;
74                 map[a][b][1]=map[b][a][1]=d;
75             }
76         }
77         memset(v,0,sizeof(v));
78         scanf("%d%d",&a,&b);
79         dijk(a);
80         printf("%d %d\n",s1[b],s2[b]);
81     }
82 }
复制代码

 

posted on   pb2016  阅读(581)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)

点击右上角即可分享
微信分享提示