L2-001 紧急救援 (25 分)

#include<iostream>
#include<vector>
#define iIN(a,b) for(int i=a;i<b;i++)
using namespace std;
const int MAX=0xfffffff;
int map[505][505];//存放路径信息
//初始化 
int rescue[505];  //救援队数量
int num[505];     //到这里有几条路径 
int road_rescue[505];//路径上的救援队 
//需要输入的数组 
int vis[505];     //记录标星信息
//自动初始化为0 
int tolen[505];   //记录其实点到i点的最短距离 刚开始是MAX 然后逐渐松弛 
//初始化为0或MAX 
vector<int> road[505];
void init(){
	for(int i=0;i<505;i++){
		tolen[i]=MAX;
		for(int j=0;j<505;j++){
			if(i==j)map[i][j]=0;
			else map[i][j]=MAX;
		}
	}
}
int main(){
	
	int N;//几个城市
	int M;//几条道路
	int start,fina;//起始点 终点
	int from,to,len;	
	cin>>N>>M;
	cin>>start>>fina;
	init(); //初始化数组
		
	//输入rescue
	for(int i=0;i<N;i++){
		cin>>rescue[i];
	}
	//输入图信息 
	for(int i=0;i<M;i++){
		cin>>from>>to>>len;
		if(map[from][to]>len){
			map[from][to]=len;
			map[to][from]=len;
		}
	}
	//dijkstra
	
	
	road_rescue[start]=rescue[start];
	num[start]=1;
	vis[start]=1;
	road_rescue[start]=rescue[start];
	for(int i=0;i<N;i++){
		if(map[start][i]<tolen[i] && i!=start){
			tolen[i]=map[start][i];
			road_rescue[i]=road_rescue[start]+rescue[i];//营救队
			road[i].push_back(start);
			road[i].push_back(i);
			num[i]=num[start];
		}
	}
	
	
	while(1){
		int which=-1;
		int which_len=MAX;
		for(int i=0;i<N;i++){
			if(vis[i])continue;
			if(tolen[i]<which_len){
				which=i;
				which_len=tolen[i];
			}
		}
		if(which==-1)break;
		vis[which]=1;
		for(int i=0;i<N;i++){
			if(vis[i])continue;
			if(map[which][i]==MAX)continue;
			if(tolen[which]+map[which][i]<tolen[i])
			{
				tolen[i]=tolen[which]+map[which][i];
				//增加路径 
				road[i].assign(road[which].begin(),road[which].end());
				road[i].push_back(i);
				//修改road_rescue 
				road_rescue[i]=road_rescue[which]+rescue[i];
				num[i]=num[which];
			} 
			else if(tolen[which]+map[which][i]==tolen[i])
			{
				num[i]+=num[which];
				if(road_rescue[which]+rescue[i]>road_rescue[i]){
					tolen[i]=tolen[which]+map[which][i];
					//增加路径 
					road[i].assign(road[which].begin(),road[which].end());
					road[i].push_back(i);
					//修改road_rescue 
					road_rescue[i]=road_rescue[which]+rescue[i];
					
				}
			}
		}
	}
	cout<<num[fina]<<" "<<road_rescue[fina]<<endl;
	int TI=0;
	iIN(0,road[fina].size()){
		if(TI)cout<<" ";
		TI=1;
		cout<<road[fina][i];
	}
	cout<<endl;
	return 0;
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

会写代码的孙悟空

赠人玫瑰 手有余香

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

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

打赏作者

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

抵扣说明:

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

余额充值