L2-001 紧急救援 (25 分)

时间:2019-02-19
本文章向大家介绍L2-001 紧急救援 (25 分),主要包括L2-001 紧急救援 (25 分)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

传送门

#include<cstdio>
#include<string.h>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<vector>
#define N 0x3f3f3f3f
#define p 510
using namespace std;
int s[p];
int mpp[p][p]; 
int num[p]; //节点i同长路径数目 
int pre[p]; //前驱节点 
int vis[p]; //标记 
int val[p]; //节点消防员数目 
int w[p];	//走到节点i召集的消防员最大数目  
int n,m,ss,d;
void dijskra(int x)
{
	for(int i=0;i<n;i++)
	{
		vis[i]=0,s[i]=N;
	}
	s[x]=0;
	w[x]=val[x];
	num[x]=1;
	for(int i=0;i<n;i++)
	{
		int u=-1;
		int maxx=N;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&s[j]<maxx)
			{
				u=j;
				maxx=s[j];
			}
		} 
		if(u==-1)
		break;
		vis[u]=1;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&s[j]>s[u]+mpp[u][j])
			{
				s[j]=s[u]+mpp[u][j];
				num[j]=num[u];
				w[j]=val[j]+w[u];
				pre[j]=u;
			}
			else if(!vis[j]&&s[j]==s[u]+mpp[u][j])
			{
				num[j]+=num[u];
				if(w[j]<w[u]+val[j])
				{ 
					w[j]=w[u]+val[j];
					pre[j]=u;
				}
			}
		}
	} 
	return ;
}
int find(int x)
{
	if(x==ss)
	{
		cout<<x;
		return 0; 
	}
	find(pre[x]);
	cout<<" "<<x;
	return 0;
}
int main()
{
	cin>>n>>m>>ss>>d; 
	for(int i=0;i<n;i++) 
	{
		cin>>val[i];
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			mpp[i][j]=N;
		}
	}
	for(int i=0;i<m;i++)
	{
		int x,y,z;
		cin>>x>>y>>z;
		mpp[x][y]=mpp[y][x]=z;
	}
	dijskra(ss);
	cout<<num[d]<<" "<<w[d]<<endl;
	find(d);
	return 0;
}