IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> pta a.1003 的收获 -> 正文阅读

[数据结构与算法]pta a.1003 的收获

pta a.1003 的收获

题目

在这里插入图片描述

对于题目的收获

这是英文的题目,在这里面我犯的错有两个

  1. 我在模型提炼的时候把题目中的路搞成了有向图,这个是非常荒谬的。在没有说明的情况下,路一定是无向图。
  2. 最后的输出第一个要的是:the number of different shortest paths between c1 and c2 也就是不同最短路径的条数。

思路

其实通过题目一下子就可以看出这是最短路径的一个模型应用,只不过在上面加入了最短路径条数和点权的问题。

解决

首先是最短路径,这里用的是dijkstra

const int MAXN=510;
const int INF=100000000;
int GM[MAXN][MAXN];
int visit[MAXN];
int dis[MAXN];
int num[MAXN];
int n,m,c1,c2;
void myfunc(int s);
struct node{
	int self;
	int sum;
};
node weight[MAXN];
void myfunc(int s)
{
	dis[s]=0;
	weight[s].sum=weight[s].self;  
	num[s]=1;
	int x;
	int MIN;
	for(int k=0;k<n;k++)
	{
		x=-1;
		MIN=INF;
		for(int i=0;i<n;i++)
		{
			if(visit[i]==false&&dis[i]<MIN)
			{
				x=i;
				MIN=dis[i];
			}
			
		}
		if(x==-1)return;//没找到说明顶点与剩下的不连通直接退
		visit[x]=true;
		for(int i=0;i<n;i++)
		{
			if(visit[i]==false&&GM[x][i]!=INF)
			{
				if(dis[i]>dis[x]+GM[x][i])
				{
					dis[i]=dis[x]+GM[x][i];
					weight[i].sum=weight[i].self+weight[x].sum; 
					num[i]=num[x];
					 
					
				}
				else if(dis[i]==dis[x]+GM[x][i]   )
				{
					if(weight[i].sum<weight[i].self+weight[x].sum)
					{
						weight[i].sum=weight[i].self+weight[x].sum;
					   }
					num[i]+=num[x];   
					
				}
				
			}
		}
	}

	
}

收获

  1. 对于图来讲,不连通的表示方式是设一个INF这个值,还是有所讲究的。第一是要够大,所以胡凡推荐了两个 1000000000 也就是1e9还有就是0x3fffffff,但是不要太大,因为常有两个边相加如果二者加和超过了int的范围就会出错比如0x7fffffff。
  2. 由于算法要求的一步步的纳入,所以要区分已纳入和未纳入。由此就有了visit[]数组。这一点我还是有一个疑惑,也就是这个算法是不是贪心算法的具体体现,书上没说,我也不太清楚,留到以后解决。
  3. 关于两个变动,原来的算法因为只求最短距离,所以距离相等时是不做任何处理的。但是这里不行,因为我们要求最短的条数和点权最大的路,所以要在用中介调整距离的时候调整一下。下面两条就是说这个的。
  4. 首先是最短的条数
   for(int i=0;i<n;i++)
   	{
   		if(visit[i]==false&&GM[x][i]!=INF)
   		{
   			if(dis[i]>dis[x]+GM[x][i])
   			{
   				dis[i]=dis[x]+GM[x][i];
   				
   				num[i]=num[x];//1
   				 
   				
   			}
   			else if(dis[i]==dis[x]+GM[x][i]   )
   			{
   				
   				num[i]+=num[x];//2
   				
   			}
   			
   		}
   	}

一共两条改动,1的那里因为最短就是通过中介直达,所以条数和通过中介的一样多。2的那里是由于路程是并列的,所以他们都是最短路径所以相加。
5. 然后是最大权值
先写一个数据结构

struct node{
	int self;
	int sum;
};

这个数据结构比较关键(两个数组也行就没那么直观了)
self就是存的他本来的权值(题目里的救援队的数量)
sum是从起点到这里的目前最短路径的救援队数量的总和

		for(int i=0;i<n;i++)
		{
			if(visit[i]==false&&GM[x][i]!=INF)
			{
				if(dis[i]>dis[x]+GM[x][i])
				{
					dis[i]=dis[x]+GM[x][i];
					weight[i].sum=weight[i].self+weight[x].sum; //1
					
					 
					
				}
				else if(dis[i]==dis[x]+GM[x][i]   )
				{
				//2
					if(weight[i].sum<weight[i].self+weight[x].sum)
					{
						weight[i].sum=weight[i].self+weight[x].sum;
					   }
					
					
				}
				
			}
		}

1的这里十分易于理解,就是发现一条新的最短路径到这里就把这里的权值加上上一个的总和.2这里 weight[i].self+weight[x].sum 是新的总权值和已有的权值作比较要是原有的小就要更新

6.这个是我对dijkstra算法的一个小的要求就是在设置dis[]数组的时候把起点设为0其他设为INF,然后让程序找到起点作为第一个中介点去执行操作,这样在进行如4 5的操作才能不用去特殊照顾第一个中介点。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-08 12:01:22  更:2021-10-08 12:03:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:48:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码