L3-011 直捣黄龙 (30 分)(dijkstra+map)

本文介绍了一种使用Dijkstra算法解决最短路径问题的方法,通过将字符串节点转化为数字并利用map进行存储。在Dijkstra算法中,首先判断最短路径,然后是节点数,接着是歼敌数。代码实现包括地图节点的编号、最短路径查找和路径输出。最终,通过示例展示了如何找到从起点到终点的最短路径、最短路径数、经过的据点数和总歼敌数。
摘要由CSDN通过智能技术生成

L3-011 直捣黄龙 (30 分) (dijkstra+map)

这几天写了一些复杂的最短路的题,发现这些题都是有规律的,掌握了这些规律,任何一道最短路的题将不在话下 -

基本思路

这题变化就在于每个点不是数是一个字符串,既然这样我们转化为数就好啦。这里我想到了map容器,我们将这些据点的值从0-n-1编号,作为map[i],那么它的下标就是所对应的字符串了。然后进行dijkstra的时候先判断最短的路径,然后是节点数,再就是歼敌数了,这些都可以按照套路来了,把这个多重判断记下来其它题也就so easy了。

废话不多说直接上代码

#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<map> 
using namespace std;
const int inf=0x3f3f3f3f;
int d[500][500],vis[500],dis[500];
int path[500];  //记录路径 
int cnt[500];   //记录最短路径数 
int ret[500];   //记录经过的据点数 
int sum[500],aa[500];   //到达一据点能歼敌总数、每个据点歼敌数 
int dd;    //记录终点 
int n;
map<string,int> m;
void dfs(int k)
{
	if(k==0)
	{
		map<string,int>::iterator it;
		for(it=m.begin();it!=m.end();++it)
		{
			if(it->second==k){
				cout<<it->first;break;
			}
		}
		return;
	}
	dfs(path[k]);
	cout<<"->";
	map<string,int>::iterator it;
	for(it=m.begin();it!=m.end();++it)
		{
			if(it->second==k){
				cout<<it->first;break;
			}
		}
}
void dijkstra(int s)
{
	memset(dis,inf,sizeof(dis));
	dis[s]=0;
	cnt[s]=1;
	for(int i=0;i<n;++i)
	{
		int t=-1,minn=inf;
		for(int j=0;j<n;++j)
			if(!vis[j]&&dis[j]<minn){
				t=j;
				minn=dis[j];
			}
		vis[t]=1;
		if(t==-1)
			break;
		for(int j=0;j<n;++j)
		{
			if(!vis[j]&&(dis[j]>dis[t]+d[t][j])){
				dis[j]=dis[t]+d[t][j];
				sum[j]=sum[t]+aa[j];
				path[j]=t;
				ret[j]=ret[t]+1;
				cnt[j]=cnt[t];
			}
			else if(!vis[j]&&dis[j]==dis[t]+d[t][j])
			{
				cnt[j]+=cnt[t];
				if(ret[j]<ret[t]+1)
				{
					ret[j]=ret[t]+1;
					path[j]=t;
					sum[j]=sum[t]+aa[j];
				}
				else if(ret[j]==ret[t]+1&&sum[j]<sum[t]+aa[j])
				{
					path[j]=t;
					sum[j]=sum[t]+aa[j];
				}
			}
		}
	}
}
int main()
{
	memset(d,inf,sizeof(d));
	for(int i=0;i<n;++i)
		d[i][i]=0;
	int k,b;
	cin>>n>>k;
	string a,c;
	getchar();
	cin>>a>>c;
	m[a]=0;
	for(int i=1;i<n;++i)
	{
		cin>>a>>b;
		if(a==c)
			dd=i;
		m[a]=i;
		aa[i]=b;
	}
	while(k--)
	{
		cin>>a>>c>>b;
		d[m[a]][m[c]]=d[m[c]][m[a]]=b;
	}
	dijkstra(0);
	dfs(dd);
	cout<<endl;
	cout<<cnt[dd]<<" "<<dis[dd]<<" "<<sum[dd];
}
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值