HDU 3790 最短路径问题

本文介绍了一种在解决最短路径问题时同时考虑路径长度与成本的算法实现。该算法通过Dijkstra变种来找到两点间最短路径的同时确保路径成本最小。适用于需要综合考量距离与费用的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://acm.hdu.edu.cn/showproblem.php?pid=3790

最短路径问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 14544    Accepted Submission(s): 4446


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:   1217  1142  2680  1385  1598 
这道题还是很有价值的,第一眼看过去感觉很简单,写下去之后错了还能多次,则题主要注意当最短路径相同是,得比较花费,选最低的花费;

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>
#define INF 1<<20
#define maxn 10000+5
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define mod 90001
#define PI 3.141592657

const ull inf = 1LL << 61;
const double eps=1e-5;

using namespace std;

bool cmp(int a,int b){
return a>b;
}
struct edge
{
int p,dist;
}edge[1005][1005];
int n,m;
int a,b,s,t,d,p;
int spend[1005],lowcost[1005];
int vis[1005];
void dj(int s)
{
cle(vis);
vis[s]=1;
for(int i=1;i<=n;i++)
{
lowcost[i]=edge[s][i].dist;
spend[i]=edge[s][i].p;
}
int Min=INF,k;
while(1)
{
Min=INF;
for(int j=1;j<=n;j++)
if(lowcost[j]<Min&&!vis[j])
{
Min=lowcost[j];k=j;
}
if(Min==INF)break;
vis[k]=1;
for(int j=1;j<=n;j++)
{
if(lowcost[k]+edge[k][j].dist<lowcost[j]&&!vis[j])
{
lowcost[j]=lowcost[k]+edge[k][j].dist;
spend[j]=spend[k]+edge[k][j].p;
}
else if(lowcost[k]+edge[k][j].dist==lowcost[j]&&!vis[j])
if(spend[k]+edge[k][j].p<spend[j])
{
lowcost[j]=lowcost[k]+edge[k][j].dist;
spend[j]=spend[k]+edge[k][j].p;
}
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(cin>>n>>m)
{
if(n==0&&m==0)break;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
edge[i][j].dist=INF;edge[i][j].p=INF;
edge[j][i].dist=INF;edge[j][i].p=INF;
}
edge[i][i].dist=0;
edge[i][i].p=0;
}
for(int i=1;i<=m;i++)
{
//cin>>a>>b>>d>>p;
scanf("%d%d%d%d",&a,&b,&d,&p);
if(edge[a][b].dist>d)
{
edge[a][b].dist=d;edge[b][a].dist=d;
edge[a][b].p=p;edge[b][a].p=p;
}
}
scanf("%d%d",&s,&t);
dj(s);
cout<<lowcost[t]<<" "<<spend[t]<<endl;
}
return 0;
}


最短路径问题hdu-3790--Dijkstra - 风未定 - Guanjun的博客~~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值