我将树与图章节我认为还不太熟练的代码实现重温了一遍,今天的总结便是我重新手敲的代码
图的遍历:
#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;
}