实验七 图的操作
一、实验目的
1、掌握图的基本概念,描述方法;遍历方法。
二、实验内容
1、创建图类。二叉树的存储结构使用邻接矩阵或链表。
2、提供操作:遍历、BFS、DFS
3、对建立好的图,执行上述各操作。
4、输出生成树。
1、 输出最小生成树。
实验七 图的操作
一、 要求完成时间
实验开始后的第八周之前完成
二、 实验目的
掌握图的基本概念,描述方法;遍历方法。
三、 实验内容
1、 创建图类,存储结构使用邻接矩阵。
2、 输入图的节点数n(不超过10个)、边数m,节点分别用1-n代表。
3、 采用“起始节点,终止节点,权值”输入图的m条边,创建图。
4、 输出从节点1开始的BFS遍历。
5、 输出从节点1开始的DFS遍历。
6、 输出从第1节点到第n节点最短路径的长度,如果没有路经,输出0。
7、 输出最小生成树的所有边。输出格式采用“起始节点-终止节点:权值”,小的节点在前,大的节点在后,每个边独立一行输出,例如1-2:12是正确的,2-1:12是错误的。
两个不同的版本要求结合着看吧。
bfs,dfs不再赘述,请自行百度。
说重点的kruskal算法:核心操作就是一个,对所有的边按照话费进行自然排序,然后从小花费的边开始,逐条加入,保证加入的这条边使得已经加入的边不会构成环。这里一般用并查集来做。我的代码里也用了路径压缩。并查集的部分请戳这里:http://www.cnblogs.com/Findxiaoxun/p/3427584.html
下面是实验的代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<queue>
using namespace std; const int MAXN=100; int n,m; struct node{ int u,v,dis; node(){ u=v=dis=0; } bool operator < (const node& tmp) const{ return dis<tmp.dis; } }; //use disjoint-set
struct disjointset{ int father[MAXN]; void initial(){ for(int i=0;i<=n;father[i]=i,i++); } int getfather(int v){ if(father[v]==v)return v; return father[v]=getfather(father[v]); } bool issame(int a,int b){ return getfather(a)==getfather(b); } void unioned(int u,int v){ int fu=father[u],fv=father[v]; father[fv]=fu; } }; struct map{ int mymap[MAXN][MAXN]; int n,m; queue<int>bfsans; queue<int>dfsans; bool visit[MAXN]; node gra[MAXN]; int len,minlen,shortestway; int track[MAXN];//just record the pre node
void create(int an,int am){ int x,y,z; //x:row y:col
n=an;m=am; len=0;minlen=0; for(int i=0;i<am;i++){//without direction
scanf("%d%d%d",&x,&y,&z); gra[len].u=x; gra[len].v=y; gra[len++].dis=z; mymap[x][y]=z; mymap[y][x]=z; } sort(gra,gra+len); memset(visit,0,sizeof(visit)); memset(track,-1,sizeof(track)); } void BFS(int id){ queue<int>que; que.push(id); memset(visit,0,sizeof(visit)); int i; visit[id]=true; while(!que.empty()){ i=que.front(); bfsans.push(i); que.pop(); for(int j=1;j<=n;j++){ if(j==i)continue; if(mymap[i][j]&&!visit[j]){ track[j]=id; que.push(j); visit[j]=1; } } } //the belowing is the way to find the track of you
memset(visit,0,sizeof(visit)); if(!track[n]){shortestway=0;return;} i=n; while(i!=1){ minlen+=mymap[i][track[i]]; i=track[i]; } shortestway=minlen; } void DFS(int id){//remember the root
visit[id]=1; for(int i=1;i<=n;i++){ if(i==id)continue; if(!visit[i]&&mymap[id][i]>0){ dfsans.push(i); DFS(i); } } } void output(){ printf("Here is the BFS track:\n"); while(!bfsans.empty()){ printf("%d ",bfsans.front()); bfsans.pop(); } printf("\nHere is the DFS track:\n1 "); while(!dfsans.empty()){ printf("%d ",dfsans.front()); dfsans.pop(); } printf("\nthe shortest way from 1 to n\n%d\n",shortestway); } void Kruskal(){ disjointset jihe; jihe.initial(); int id=0,counter=1,ans=0;//counter:must be n-1
printf("Min ShengChengShu:\n"); int a,b,c; while(counter<n||id<len){ a=gra[id].u; b=gra[id].v; c=gra[id].dis; if(!jihe.issame(a,b)){ ans+=c; counter++; jihe.unioned(a,b); if(a<b)swap(a,b); printf("%d-%d:%d\n",a,b,c); } id++; } printf("the min cost:%d",ans); } }; int main(){ map yourmap; printf("Input your nodes and edges:\n"); scanf("%d%d",&n,&m); yourmap.create(n,m); yourmap.BFS(1); yourmap.DFS(1); yourmap.output(); yourmap.Kruskal(); return 0; }