数据结构第五次作业(图的基本操作实现)
2016-10-31 21:46
399 查看
实验题目: 图的基本操作实现
实验目的:掌握图的邻接矩阵和邻接表两个存储结构及表示。
掌握图的DFS和BFS两种遍历算法。
理解并掌握下述完整算法的基本思想以及算法实现方法:最小生成树算法、最短路径算法、拓扑排序算法及关键路径算法。
实验内容:1. 创建一个无向图,并分别对其进行DFS和BFS。
2. 实现最短路径、最小生成树、拓扑排序三种算法。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<queue>
using namespace std;
const int INF=1e8-1;
int n,m;
bool vis[1010];
int dist[1010];
int indegree[1010];
bool mark[1010][1010];
int map[1010][1010];
int road[1010][1010];
/* 测试数据
1 2 6
1 3 11
1 4 5
2 3 4
2 4 7
3 4 9
*/
void dfs(int x) // 深搜
{
cout<<x;
vis[x]=1;
for(int i=2;i<=n;i++)
{
if(!vis[i]&&map[x][i]!=INF)
dfs(i);
}
}
void bfs(int x) // 广搜
{
cout<<x;
vis[x]=1;
queue<int> Q;
Q.push(x);
while(!Q.empty())
{
int t;
t=Q.front();
Q.pop();
for(int i=2;i<=n;i++)
{
if(!vis[i]&&map[x][i]!=INF)
{
cout<<i;
vis[i]=1;
Q.push(i);
}
}
}
}
int prim() // 普里姆算法求最小生成树
{
int ans=0;
for(int i=0;i<1010;i++)
dist[i]=INF;
dist[1]=0;
for(int i=1;i<=n;i++)
{
int k,tp=INF;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&dist[j]<tp)
{
k=j;
tp=dist[j];
}
}
vis[k]=1;
ans+=tp;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&map[k][j]<dist[j])
{
dist[j]=map[k][j];
}
}
}
return ans;
}
void floyd() // 佛洛伊德算法求最短路
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
road[i][j]=map[i][j];
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
road[i][j]=min(road[i][j],road[i][k]+road[k][j]);
}
}
}
}
void topo()
{
int tpsort[1010];
int x,num=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(indegree[j]==0)
{
x=j;
break;
}
}
tpsort[num++]=x;
indegree[x]=-1;
for(int j=1;j<=n;j++)
{
if(mark[x][j])
indegree[j]--;
}
}
for(int i=0;i<num;i++)
printf(i==num-1?"%d\n":"%d ",tpsort[i]);
}
int main()
{
printf("\n********************************\n\n");
puts("1. 建图");
puts("2. DFS遍历");
puts("3. BFS遍历");
puts("4. 连通该图所有顶点的最小代价");
puts("5. 两点之间的最短路径");
puts("6. 输出拓扑排序后的序列");
puts("0. 退出");
printf("\n********************************\n\n");
int choose;
while(scanf("%d",&choose),choose)
{
switch(choose)
{
case 1:
printf("请分别输入图的顶点总数和边的总数:");
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
map[i][j]=(i==j?0:INF);
}
}
printf("请输入边的两个端点及权值:\n");
memset(indegree,0,sizeof(indegree));
memset(mark,0,sizeof(mark));
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(map[u][v]>w)
map[u][v]=map[v][u]=w;
if(!mark[u][v])
{
mark[u][v]=1;
indegree[v]++;
}
}
puts("成功建图\n");
break;
case 2:
memset(vis,0,sizeof(vis));
dfs(1);
puts("\n");
break;
case 3:
memset(vis,0,sizeof(vis));
bfs(1);
puts("\n");
break;
case 4:
memset(vis,0,sizeof(vis));
printf("最小代价为:%d\n\n",prim());
break;
case 5:
floyd();
printf("请输入您想要查询的两个点:");
int a,b;
scanf("%d%d",&a,&b);
printf("两点之间的最短路径为:%d\n\n",road[a][b]);
break;
case 6:
topo();
puts("\n");
break;
}
}
system("pause");
return 0;
}
实验目的:掌握图的邻接矩阵和邻接表两个存储结构及表示。
掌握图的DFS和BFS两种遍历算法。
理解并掌握下述完整算法的基本思想以及算法实现方法:最小生成树算法、最短路径算法、拓扑排序算法及关键路径算法。
实验内容:1. 创建一个无向图,并分别对其进行DFS和BFS。
2. 实现最短路径、最小生成树、拓扑排序三种算法。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<queue>
using namespace std;
const int INF=1e8-1;
int n,m;
bool vis[1010];
int dist[1010];
int indegree[1010];
bool mark[1010][1010];
int map[1010][1010];
int road[1010][1010];
/* 测试数据
1 2 6
1 3 11
1 4 5
2 3 4
2 4 7
3 4 9
*/
void dfs(int x) // 深搜
{
cout<<x;
vis[x]=1;
for(int i=2;i<=n;i++)
{
if(!vis[i]&&map[x][i]!=INF)
dfs(i);
}
}
void bfs(int x) // 广搜
{
cout<<x;
vis[x]=1;
queue<int> Q;
Q.push(x);
while(!Q.empty())
{
int t;
t=Q.front();
Q.pop();
for(int i=2;i<=n;i++)
{
if(!vis[i]&&map[x][i]!=INF)
{
cout<<i;
vis[i]=1;
Q.push(i);
}
}
}
}
int prim() // 普里姆算法求最小生成树
{
int ans=0;
for(int i=0;i<1010;i++)
dist[i]=INF;
dist[1]=0;
for(int i=1;i<=n;i++)
{
int k,tp=INF;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&dist[j]<tp)
{
k=j;
tp=dist[j];
}
}
vis[k]=1;
ans+=tp;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&map[k][j]<dist[j])
{
dist[j]=map[k][j];
}
}
}
return ans;
}
void floyd() // 佛洛伊德算法求最短路
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
road[i][j]=map[i][j];
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
road[i][j]=min(road[i][j],road[i][k]+road[k][j]);
}
}
}
}
void topo()
{
int tpsort[1010];
int x,num=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(indegree[j]==0)
{
x=j;
break;
}
}
tpsort[num++]=x;
indegree[x]=-1;
for(int j=1;j<=n;j++)
{
if(mark[x][j])
indegree[j]--;
}
}
for(int i=0;i<num;i++)
printf(i==num-1?"%d\n":"%d ",tpsort[i]);
}
int main()
{
printf("\n********************************\n\n");
puts("1. 建图");
puts("2. DFS遍历");
puts("3. BFS遍历");
puts("4. 连通该图所有顶点的最小代价");
puts("5. 两点之间的最短路径");
puts("6. 输出拓扑排序后的序列");
puts("0. 退出");
printf("\n********************************\n\n");
int choose;
while(scanf("%d",&choose),choose)
{
switch(choose)
{
case 1:
printf("请分别输入图的顶点总数和边的总数:");
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
map[i][j]=(i==j?0:INF);
}
}
printf("请输入边的两个端点及权值:\n");
memset(indegree,0,sizeof(indegree));
memset(mark,0,sizeof(mark));
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(map[u][v]>w)
map[u][v]=map[v][u]=w;
if(!mark[u][v])
{
mark[u][v]=1;
indegree[v]++;
}
}
puts("成功建图\n");
break;
case 2:
memset(vis,0,sizeof(vis));
dfs(1);
puts("\n");
break;
case 3:
memset(vis,0,sizeof(vis));
bfs(1);
puts("\n");
break;
case 4:
memset(vis,0,sizeof(vis));
printf("最小代价为:%d\n\n",prim());
break;
case 5:
floyd();
printf("请输入您想要查询的两个点:");
int a,b;
scanf("%d%d",&a,&b);
printf("两点之间的最短路径为:%d\n\n",road[a][b]);
break;
case 6:
topo();
puts("\n");
break;
}
}
system("pause");
return 0;
}
相关文章推荐
- 数据结构第四次作业(二叉树的基本操作实现)
- 重学数据结构004――栈的基本操作及实现(数组实现)
- javascript实现数据结构: 树和二叉树,二叉树的遍历和基本操作
- 数据结构复习--java实现单链表基本操作
- 算法与数据结构--图的实现、基本操作及应用
- 【C++数据结构】几种单链表的模类板实现及基本操作
- 重学数据结构004——栈的基本操作及实现(数组实现)
- [数据结构][C语言]图的基本介绍和操作实现之基本概念
- 数据结构:二叉树的基本操作(JAVA实现)
- 【 数据结构】实现二叉树以及其基本操作
- 数据结构之队列定义及基本操作实现
- hrbustoj 1545:基础数据结构——顺序表(2)(数据结构,顺序表的实现及基本操作,入门题)
- 【数据结构】双向循环线性表的基本操作--C++/C实现
- 【数据结构】双向循环线性表的基本操作--C++/C实现
- 数据结构:字符串的堆分配存储结构,基本操作实现和测试。
- 算法与数据结构--图的实现、基本操作及应用
- 数据结构--串的操作基本实现程序代…
- PHP数据结构之五:栈的PHP的实现和栈的基本操作
- 数据结构之链表定义及基本操作实现
- 【C++数据结构】模版类实现双循环链表的基本操作