pat甲级1003

本文介绍了一种使用Dijkstra算法解决特定最短路径问题的方法。该问题不仅要求找出两个点之间的最短路径,还需要统计这样的最短路径数量及路径上救援人员的最大数量。文章详细展示了算法实现过程,并分享了作者在实现过程中遇到的问题及解决方案。

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

这道题典型的求最短路径的算法,用Djktra算法写。关键点是要求出最短路径个数和最短路径中救援人员最多的人数,一开始想先求出最短距离再用DFS扫出最短路径,但在DFS中不好控制起点与终点路径扫描次序也会不同,递归的方法真的很绕人啊!

在Djktra算法中可以用在线处理的方法求出最短路径个数,当出现更短的路径时“重设”救援人数和路径计数,当出现相等路径时计数增加,救援人数如果更大再更新!

但发现一个问题,当我采用将当前最小的路径距离和最大的人数存起来再进行比对时无法ac。显示答案错误,

#include<iostream>
//#include<cstdio>
#define INF 65535
using namespace std;
int map[510][510];
void initialmap()
{
	int i,j;
	for(i=0;i<510;i++)
		for(j=0;j<510;j++)
		{
			if(i==j)
			map[i][j]=0;
			else
				map[i][j]=INF;
		}
}


int findmin(int dist[],bool collect[],int n)
{
	int i,min=INF,v=-1;
	for(i=0;i<n;i++)
	{
		if(collect[i]==false&&dist[i]<min)
		{
				v=i;
				min=dist[i];
		}
	}
	return v;


}
int main()
{
	int n,m,i,j,d,t,cnt[520]={0},s,tem=0;
    int team[520]={0},dist[520],vetex[520]={0},weight[520]={0};
    int min[520],wmax[520],tag=0;
    bool collect[520];
    int c1,c2;
	//freopen("path.in.txt","r",stdin);
	//freopen("path.out","w",stdout);
	cin>>n>>m>>c1>>c2;
	initialmap();
	for(t=0;t<n;t++)
	{
		cin>>team[t];
	}
	while(m--)
	{
		cin>>i>>j>>d;
		map[i][j]=d;
		map[j][i]=d;
	}
		
	for(i=0;i<n;i++)
	{
		dist[i]=INF;
		collect[i]=false;
		vetex[i]=1;
		min[i]=INF;
		wmax[i]=0;
		cnt[i]=1;
	}
	//t=team[c1];
	weight[c1]=team[c1];
	dist[c1]=0;
	int v; 
	while(v!=c2)
	{
		v=findmin(dist,collect,n);
		if(v==-1)
			break;
		collect[v]=true;
		for(i=0;i<n;i++)
		{
			if(collect[i]==false&&map[v][i]!=INF)
			{
			if((map[v][i]+dist[v])<dist[i])
			{
				dist[i]=map[v][i]+dist[v];
				weight[i]=team[i]+weight[v];
				cnt[i]=cnt[v];
			}
			else
				if((map[v][i]+dist[v])==dist[i])
				{
					cnt[i]+=cnt[v];
					if(weight[i]<team[i]+weight[v])
						weight[i]=team[i]+weight[v];
				}
				/*if(dist[i]<min[i])
				{
					min[i]=dist[i];
					cnt[i]=cnt[v];
					wmax[i]=weight[i];
				}
				else
					if(dist[i]==min[i])
					{
						cnt[i]=cnt[i]+cnt[v];
						if(weight[i]>wmax[i])
							wmax[i]=weight[i];
					}*/
			//	cout<<"--"<<v<<","<<i<<weight[i]<<endl;
				/*if(i==c2)
					tag=1;*/
			
			}
		}
/*		if(tag==1)//一开始的想法,发现这样求出路径的个数c2之前的所有节点不可有俩条相同的最短路径才能正确
		{
		if(dist[c2]<min)
		{
		//	cout<<cnt<<endl;
			min=dist[c2];
			wmax=weight[c2];
			cnt=1;
		}
		else if(dist[c2]==min)
		{
		//	cout<<"--"<<v<<endl;
			if(weight[c2]>wmax)
				wmax=weight[c2];
			cnt++;
		//	cout<<"=="<<cnt<<endl;
		}
		}
		tag=0;*/
	}
	cout<<cnt[c2]<<" "<<weight[c2];
	return 0;
}


		











		











		




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值