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;
} 
发布了177 篇原创文章 · 获赞 5 · 访问量 6653

猜你喜欢

转载自blog.csdn.net/a1920993165/article/details/105565406
今日推荐