0
点赞
收藏
分享

微信扫一扫

2月14日学习总结

闲鱼不咸_99f1 2022-02-14 阅读 98
数据结构

1、早上

先看了ysj学长的博客里面的dijkstra的链式前向星和优先队列的优化代码,发现有点看不懂,然后去csdn搞懂了优先队列的大概意思,然后去写了一个dijkstra的优化题目。(3h)

#include <stdio.h>
#include <cstring>//memset
#define INF 2147483647
#define N 10001
#define M 500010
int e[N][N],dis[N],head[N],cnt;//head 链式前向星中存边的头,cnt编号 
bool book[N];
struct edge{
	int to;//边的终点 
	int w;//权重 
	int nxt;//指向同一个头的边的下一条编号 
}edges[M];
void add(int u,int v,int w){//创建链式前向星 
	edges[++cnt].to=v;
	edges[cnt].w=w;
	edges[cnt].nxt=head[u];
	head[u]=cnt;
}
int main(){
	int n,m,s;
	scanf("%d%d%d",&n,&m,&s);
	while(m--){
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
	}
    memset(dis,0x3f,sizeof(dis));//将s到其它点的距离都赋为最大值 
	dis[s]=0;//s到本身的距离为0 
	for(int i=1;i<=n-1;i++){
		int min=INF,u;
		for(int j=1;j<=n;j++){ //找dis中未确定的最小值 
			if(!book[j]&&dis[j]<min){
				min=dis[j];
				u=j;
			}
		}
	book[u]=true;//将dis中未确定的最小值确定 
	for(int j=head[u];j;j=edges[j].nxt){//根据链式前向星找出所有边的u,v,w,然后更新dis 
        int v=edges[j].to;
        if(!book[v]&&dis[v]>dis[u]+edges[j].w)
          dis[v]=dis[u]+edges[j].w;
	}	
	}
	for(int i=1;i<=n;i++)
	  printf("%d ",dis[i]==0x3f3f3f3f?INF:dis[i]);
	return 0;    
}

 2、下午

首先先将不需要优化的dijkstra题目给做了,然后通过看博客还有B站视频学习dijkstra堆优化的完整过程,搞懂了整个优先队列对dijkstra优化的原理,之后在读代码时不太了解c++的优先队列,于是又去看相关的博客学习,搞懂了优先队列的一些基本知识。然后通过这些知识最后将本周最后一个堆优化的dijkstra题目给做了。(3.5h)

 (1)邮递员送信

#include <stdio.h>
#define inf 99999999
#define Min(a,b) a<b?a:b
int e1[1010][1010],e2[1010][1010],dis[1010];//e1正向地图,e2反向地图 
int n,m,cnt=0;
void dijkstra(int map[1010][1010]){
	int book[1010]={0};
	for(int i=1;i<=n;i++)//初始化dis 
      dis[i]=map[1][i];
    book[1]=1;
	for(int t=1;t<=n-1;t++){
		int min=inf,u;
		for(int i=1;i<=n;i++){
			if(!book[i]&&dis[i]<min){
				min=dis[i];
				u=i;
			}
		}
		book[u]=1;
		for(int i=1;i<=n;i++){
			if(dis[i]>dis[u]+map[u][i])
			  dis[i]=dis[u]+map[u][i];
		}
	}  
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	  for(int j=1;j<=n;j++)
	    if(i==j)  e1[i][j]=e2[i][j]=0;
	    else      e1[i][j]=e2[i][j]=inf;
	while(m--){
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		e1[u][v]=Min(e1[u][v],w);//本题坑点,有可能输入两次相同的路,但权值不一样 ,所以直接存权值最小的  
		e2[v][u]=Min(e2[v][u],w);//因为是反的地图,所以要交换i,j 
	}
    dijkstra(e1);//正向走一遍 
    for(int i=1;i<=n;i++)
      cnt+=dis[i];
	dijkstra(e2);//反向走一遍 
	for(int i=1;i<=n;i++)
      cnt+=dis[i];
	printf("%d",cnt);    
	return 0; 
}

 (2)P4779 【模板】单源最短路径(标准版)

#include <bits/stdc++.h>
using namespace std; 
#define INF 99999999
#define N 100010
#define M 200010
int dis[N],head[N],cnt;//head 链式前向星中存边的头,cnt编号 
bool book[N];
//pair<-dis[i],i> 把-dis[i]和i合并在一起first=-dis  second=i ;priority_queue默认为大项堆即整个队列降序,而给first前添负号,可以正好反过来形成小项堆 
priority_queue<pair<int, int> > q;
struct edge{
	int to;//边的终点 
	int w;//权重 
	int nxt;//指向同一个头的边的下一条编号 
}edges[M];
void add(int u,int v,int w){//创建链式前向星 
	edges[++cnt].to=v;
	edges[cnt].w=w;
	edges[cnt].nxt=head[u];
	head[u]=cnt;
}
int main(){
	int n,m,s;
	scanf("%d%d%d",&n,&m,&s);
	while(m--){
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
	}
    memset(dis,0x3f,sizeof(dis));//将s到其它点的距离都赋为最大值 
	dis[s]=0;//s到本身的距离为0 
    q.push(make_pair(0,s));//初始化队列  把dis[s]和s存进去  
    while(!q.empty()){
          int u=q.top().second;//每次拿出最小dis值的下标   
          q.pop();//已拿出就出队 
          if(book[u]) continue;  //防止已出队数据重复入队,用book标记 
	      book[u]=true;//标记为已出队 
	      for(int j=head[u];j;j=edges[j].nxt){//根据链式前向星找出所有边的u,v,w,然后更新dis 
              int v=edges[j].to;
              if(!book[v]&&dis[v]>dis[u]+edges[j].w){
              	 dis[v]=dis[u]+edges[j].w;
              	 q.push(make_pair(-dis[v],v));//把更小的dis入队 
			  }
	}	
	}
	for(int i=1;i<=n;i++)
	  printf("%d ",dis[i]);
	return 0;    
}

 3、晚上

首先在复习前几天学习的知识点,过了一遍写的博客和代码,把之前写的每道题都重新搞懂,然后进行答辩,最后把今天的题解还有学习报告写完。(2.5h)

今日总共学习时长9h。

举报

相关推荐

2月15日学习总结

2月17日总结

2022年2月9日学习总结

1月23日学习总结

0 条评论