树与图的关键知识复习

我将树与图章节我认为还不太熟练的代码实现重温了一遍,今天的总结便是我重新手敲的代码

图的遍历:
 

#include<stdio.h>
struct data{
	int next,to;
};
struct data edge[1000];
int fist[100],cnt,n,m,vis[100],head,tail,book[100];
void add(int x,int y){
	edge[++cnt].to=y;
	edge[cnt].next=fist[x];
	fist[x]=cnt;
}
void dfs(int x){
	printf("%d ",x);
	book[x]=1;
	for(int i=fist[x];i!=0;i=edge[i].next){
		if(book[edge[i].to]==0){
			dfs(edge[i].to);
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		add(a,b);
	}
	dfs(1);
	return 0;
}

普里姆算法:

#include<stdio.h>
struct data{
	int to,next,w;
};
struct data edge[2000005];
int dis[2000005],book[2000005],n,m,count,cnt,head[2000005],inf=99999999,ans;
void add(int x,int y,int z){
	edge[++cnt].to=y;
	edge[cnt].next=head[x];
	edge[cnt].w=z;
	head[x]=cnt;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		dis[i]=inf;
	}
	for(int i=1;i<=m;i++){
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		add(a,b,c);
		add(b,a,c);
	}
	dis[1]=0;
	book[1]=1;
	count++;
	for(int i=head[1];i!=0;i=edge[i].next){
		if(dis[edge[i].to]>edge[i].w){
			dis[edge[i].to]=edge[i].w;
		}
	}
	while(count<n){
		int min=inf,minx;
		for(int i=1;i<=n;i++){
			if(book[i]==0&&dis[i]<min){
				min=dis[i],minx=i;
			}
		}
		book[minx]=1,count++,ans+=dis[minx];
		for(int i=head[minx];i!=0;i=edge[i].next){
			if(dis[edge[i].to]>edge[i].w){
				dis[edge[i].to]=edge[i].w;
			}
		}
	}
	printf("%d",ans);
	return 0;
}

迪杰斯特拉算法:

#include<stdio.h>
//链式向前星存图
struct data{
	int to,next,w;
};
struct data edge[100];
int head[100],cnt,n,m,s,inf=99999999,dis[100],book[100];
void add(int x,int y,int z){
	edge[++cnt].to=y;
	edge[cnt].next=head[x];
	edge[cnt].w=z;
	head[x]=cnt;
}
int main(){
	scanf("%d%d%d",&n,&m,&s);
	for(int i=1;i<=n;i++){
		dis[i]=inf;
	}
	for(int i=1;i<=m;i++){
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		add(a,b,c);
	}
	int pos=s;
	dis[pos]=0;
	while(book[pos]==0){
		book[pos]=1;
		int min=inf;
		for(int i=head[pos];i!=0;i=edge[i].next){
			if(dis[edge[i].to]>dis[pos]+edge[i].w){
				dis[edge[i].to]=dis[pos]+edge[i].w;
			}
		}
		for(int i=1;i<=n;i++){
			if(dis[i]<min&&book[i]==0){
				min=dis[i];
				pos=i;
			}
		}
	}
	for(int i=1;i<=n;i++){
		printf("%d ",dis[i]);
	}
	return 0;
}

弗洛伊德算法:

#include<stdio.h>
int map[100][100],n,m,s,inf=99999999;//连接矩阵存图
int main(){
	//初始化
	scanf("%d%d%d",&n,&m,&s);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(i==j) map[i][j]=0;
			else map[i][j]=inf;
		}
	}
	for(int i=1;i<=m;i++){
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		if(map[a][b]>c){
			map[a][b]=c;
		}
	}
	//枚举可用于转移的点
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				if(map[i][j]>map[i][k]+map[k][j]){
					map[i][j]=map[i][k]+map[k][j];
				}
			}
		}
	}
	for(int i=1;i<=n;i++){
		printf("%d ",map[s][i]);
	}
	
	
	return 0;
}

拓扑排序:

#include<stdio.h>
struct data{
	int next,to;
};
struct data edge[100];
int ru[100],n,m,cnt,fist[100],vis[100],tail,head;
void add(int x,int y){
	ru[y]++;
	edge[++cnt].to=y;
	edge[cnt].next=fist[x];
	fist[x]=cnt;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		add(a,b);
	}
	for(int i=1;i<=n;i++){
		if(ru[i]==0){
			vis[tail++]=i;
		}
	}
	while(head<tail){
		for(int i=fist[vis[head]];i!=0;i=edge[i].next){
			if(ru[edge[i].to]-1==0){
				vis[tail++]=edge[i].to;
			}
			ru[edge[i].to]--;
		}
		printf("%d ",vis[head]);
		head++;
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值