PAT.A1003 Emergency

返回目录在这里插入图片描述

题意

给出N个城市,M条无向边。每个城市中都有一定数目
的救援小组,所有边的边权已知。现在给出起点和终点,求从起点到终点的最短路径条数及最短路径上的救援小组数目之和。如果有多条最短路径,则输出数目之和最大的。

样例(可复制)

5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1
//output
2 4

注意点

  1. 对dis进行初始化的时候不能使用memset
  2. 本题没有起点与终点不连通的测试点
  3. Dijkstra的思想为:一直找当前连通块能去的最短距离的点,将该点加入连通块
#include <bits/stdc++.h>
using namespace std;

int n,m,st,ed;//n个城市,m条边,起点,终点 
int city[510],dis[510],num[510],team[510];//存放每个城市的救援队数量,最短距离 ,标记访问过的城市 
bool vis[510]={false};
int G[510][510];//图 
void Dijkstra(){
	fill(dis,dis+n,INT_MAX);
	dis[st]=0;
	num[st]=1;
	team[st]=city[st];
	while(!vis[ed]){
		int MIN=INT_MAX,v;//找出目前距离最短的还没有被访问的城市
        for(int i=0;i<n;++i)
            if(!vis[i]&&MIN>dis[i]){
                MIN=dis[i];
                v=i;
            }
        vis[v]=true;//标记
        for(int i=0;i<n;++i)
            if(!vis[i]&&G[v][i]!=0&&dis[v]+G[v][i]<dis[i]){
                dis[i]=dis[v]+G[v][i];//更新最短路径长度
                num[i]=num[v];//更新最短路径数量
                team[i]=team[v]+city[i];//更新城市的救护队数量
            }else if(G[v][i]!=0&&dis[v]+G[v][i]==dis[i]){
                num[i]+=num[v];//增加最短路径数量
                team[i]=max(team[i],team[v]+city[i]);//找出能够召集最多的城市救护队数量
            }
	}
}
int main(){
	cin>>n>>m>>st>>ed;
	for(int i=0;i<n;i++)scanf("%d",&city[i]);
	int a,b,c;
	while(m--){
		scanf("%d%d%d",&a,&b,&c);
		G[b][a]=G[a][b]=c;
	}
	Dijkstra();
	cout<<num[ed]<<" "<<team[ed]<<endl;
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小怪兽会微笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值