数据结构编程——求无向图连通子图

合集下载

无向图的连通分量统计(数组)

无向图的连通分量统计(数组)

#include<iostream>#include<vector>using namespace std;#define INFINITY 0 //最大值为无限大#define MAX_VERTEX_NUM 20 //最大顶点个数bool visited[MAX_VERTEX_NUM]={false}; //数组的遍历标志//typedef enum{DG,DN,UDG,UDN} GraphKind; //{有向图,有向网,无向图,无向网} typedef struct ArcCell{int adj; //对无权图,用1或0表示是否相邻;对带权图,则为权值int* info; //边的信息} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct{int vexs[MAX_VERTEX_NUM]; //顶点向量AdjMatrix arcs; //邻接矩阵int vexnum,arcnum; //图的当前顶点数和弧数int kind; //图的类型}MGraph;int CreateUDN(MGraph &G){cout<<"请输入顶点个数和弧数:";cin>>G.vexnum>>G.arcnum;int i;for( i=0; i<G.vexnum; i++)G.vexs[i]=i+1;for( i=0; i<G.vexnum; i++){for(int j=0; j<G.vexnum; j++){G.arcs[i][j].adj=INFINITY;G.arcs[i][j].info=NULL;}}for( i=0; i<G.arcnum; i++){cout<<"请输入两个顶点和权值:";int v1,v2,w;cin>>v1>>v2>>w;G.arcs[v1-1][v2-1].adj=w;G.arcs[v2-1][v1-1].adj=w;}return 1;int CreateUDG(MGraph& G){cout<<"请输入顶点个数和弧数:";cin>>G.vexnum>>G.arcnum;int i;for( i=0; i<G.vexnum; i++)G.vexs[i]=i+1;for( i=0; i<G.vexnum; i++){for(int j=0; j<G.vexnum; j++){G.arcs[i][j].adj=INFINITY;G.arcs[i][j].info=NULL;}}for(i=0; i<G.arcnum; i++){cout<<"请输入两个顶点和权值:";int v1,v2,w;cin>>v1>>v2>>w;G.arcs[v1-1][v2-1].adj=w;G.arcs[v2-1][v1-1].adj=w;}return 1;}int CreateDN(MGraph& G){cout<<"请输入顶点个数和弧数:";cin>>G.vexnum>>G.arcnum;int i;for( i=0; i<G.vexnum; i++)G.vexs[i]=i+1;for( i=0; i<G.vexnum; i++){for(int j=0; j<G.vexnum; j++){G.arcs[i][j].adj=INFINITY;G.arcs[i][j].info=NULL;}}for( i=0; i<G.arcnum; i++){cout<<"请输入两个顶点和权值:";int v1,v2,w;cin>>v1>>v2>>w;G.arcs[v1-1][v2-1].adj=w;}return 1;}int CreateDG(MGraph& G){cout<<"请输入顶点个数和弧数:";cin>>G.vexnum>>G.arcnum;int i;for( i=0; i<G.vexnum; i++)G.vexs[i]=i+1;for( i=0; i<G.vexnum; i++){for(int j=0; j<G.vexnum; j++){G.arcs[i][j].adj=INFINITY;G.arcs[i][j].info=NULL;}}for( i=0; i<G.arcnum; i++){cout<<"请输入两个顶点和权值:";int v1,v2,w;cin>>v1>>v2>>w;G.arcs[v1-1][v2-1].adj=w;}return 1;}int CreateGraph(MGraph& G){cout<<"请输入你想要的图的类型:";cin>>G.kind;switch(G.kind){case 0:return CreateDG(G); //构造有向图case 1:return CreateDN(G); //构造有向网case 2:return CreateUDG(G); //构造无向图case 3:return CreateUDN(G); //构造无向网default:return 0;}}int FirstAdjVex(MGraph& G,int i){for(int j=0; j<G.vexnum; j++){if(G.arcs[i][j].adj!=0)return j;}return -1;}int NextAdjVex(MGraph& G,int i,int w){for(int j=w+1; j<G.vexnum; ++j){if(G.arcs[i][j].adj!=0)return j;}return -1;}void DFS(MGraph& G,int i){visited[i]=true;cout<<G.vexs[i]<<" "<<endl;for(int w=FirstAdjVex(G,i); w>=0; w=NextAdjVex(G,i,w)){ if(!visited[w])DFS(G,w);}}void DFSTraverse(MGraph& G){int number=0;for(int i=0; i<G.vexnum; i++){if(!visited[i]){number++;DFS(G,i);}}cout<<"图的连通分量有"<<number<<"个"<<endl;}int main(){MGraph G;CreateGraph(G);for(int i=0; i<G.vexnum;i++){for(int j=0; j<G.vexnum; j++)cout<<G.arcs[i][j].adj<<" ";cout<<endl;}cout<<endl;DFSTraverse(G);return 0;}。

采用邻接表存储结构,编写一个求无向图的连通分量个数的算法

采用邻接表存储结构,编写一个求无向图的连通分量个数的算法
scanf("%d",&k);
if(k==-1){
p[i].mark=0;
p[i].first=NULL;
}
else{
temp=(struct VNode*)malloc(sizeof(struct VNode));
temp->position=k;
temp->next=NULL;
p[i].first=temp;
#include<malloc.h>
int n;
struct VNode{ //顶点
int position;
struct VNode* next;
};
struct ArcNode{ //弧
int mark;
struct VNode* first;
};
void DFS(struct ArcNode* v,struct ArcNode* w){ //深度优先搜索
[输出]
连通分量的个Βιβλιοθήκη 。[存储结构]图采用邻接矩阵的方式存储。
[算法的基本思想]
用到深度优先搜索,先从任意一个顶点开始进行深度优先搜索,搜索完后,连通分量个数增1。然后再从没有遍历过的顶点找一个出来进行深度优先搜索,搜索完后,连通分量个数增1。一直到所有的顶点都被遍历过。
[参考源程序]
#include<stdio.h>
p[i].mark=0;
flag=temp;
scanf("%d",&k);
while(k!=-1){
temp=(struct VNode*)malloc(sizeof(struct VNode));
temp->position=k;

求无向连通图的最小生成树算法

求无向连通图的最小生成树算法

求无向连通图‎的最小生成树‎算法——Prim与K‎r uskal‎及相关优化最小生成树是‎图论里很重要‎的部分。

但是由于它属‎于图论所以N‎O IP基本不‎考,对于NOI又‎太基础,所以竞赛中出‎现的几率比较‎小,即使要考也不‎可能考裸的生‎成树算法= =最小生成树就‎P rim和K‎r uskal‎两个算法,又没有多大的‎优化余地,所以学习起来‎还是很简单的‎。

一.Prim算法‎1.算法思想对于图G=(V,E),用Prim算‎法求最小生成‎树T=(S,TE)的流程如下① 初始化:设S、TE为空集,任选节点K加‎入S。

②选取一条权值‎最小的边(X,Y),其中X∈S,且not (Y∈S)即,选取一条权值‎最小的、连接着S中一‎点与S外一点‎的边。

将Y加入S中‎,边(X,Y)加入TE中重复② 直到V=S即所有G中‎的点都在S中‎,此时的T为G‎的最小生成树‎。

由此流程可见‎,Prim算法‎求最小生成树‎时任何时候的‎T都是一颗树‎。

2.实现显然,Prim算法‎的主要运行时‎间花在过程②的选边中。

看起来复杂度‎是O(VE)=O(V^3)不是么,效率也太低了‎吧……为了比较快速‎地选边,我们用两个数‎组lowco‎s t、closes‎t动态地维护‎每一个点到S‎的最短距离。

在某一状态下‎,lowcos‎t[i]表示所有与i‎相连且另一端‎点在S中的边‎中的权值最小‎值,closes‎t[i]表示在S中且‎与i相连的点‎中与i之间距‎离最小的点。

显然,lowcos‎t[i]=w(i,closes‎t[i])。

需要注意的是‎两个数组记录‎的都是边而不‎是路径。

若i没有边直‎接连向S,则lowco‎s t[i]=∞。

另外,若i已在S中‎,则lowco‎s t[i]=0。

设出发点为x‎。

初始时对于任‎意k∈V,closes‎t[k]=x,lowcos‎t[k]=w(k,x)【w(i,j)表示i、j间的距离。

初始化时,若两点间没有‎边则w(i,j)赋为一个足够‎大的整数(如maxin‎t),并且所有点到‎自身的距离赋‎为0,即w(i,i)=0】每一次找出l‎o wcost‎中不为0的最‎小值lowc‎o st[i],然后把i加入‎S(即lowco‎s t[i]:=0),然后对于图中‎所有点k,若w(k,i)<lowcos‎t[k],则把lowc‎o st[k]赋为w(k,i),把close‎s t[k]赋为i。

无向图的连通分支问题 - 算法与数据结构

无向图的连通分支问题 - 算法与数据结构

无向图的连通分支问题
«问题描述:
试设计用并查集来计算一个无向图的连通分支的算法。

«编程任务:
对于给定的无向图G,用并查集编程计算无向图G的连通分支。

«数据输入:
由文件input.txt给出输入数据。

第一行有3个正整数n,k和m,分别表示无向图G有n个顶点和k条边,m是查询顶点对个数。

接下来的k+m行,每行有2个正整数。

前k行给出图G的k条边(可能重复);后m行是查询顶点对。

«结果输出:
对于每个查询顶点对(i,j),将计算结果依次输出到文件output.txt。

如果顶点i和顶点j 属于图G的同一连通分支,则输出“Yes”,否则输出“No”。

输入文件示例输出文件示例
input.txt output.txt
10 3 3 1 2
3 4
1 3
2 3
1 4
5 6 Yes Yes No。

1040 【图论基础】求连通子图的个数 1041 【图论基础】求最小生成树(prim)

1040 【图论基础】求连通子图的个数 1041 【图论基础】求最小生成树(prim)

【图论基础】求连通子图的个数Time Limit:10000MS Memory Limit:65536KTotal Submit:42 Accepted:30Description求一个无向图中连通子图的个数。

Input第一行一个数n,表示无向图的顶点的数量(n<=5000),接下来从第2行到第n+1行,每行有n个数(1表示相应点有直接通路,0表示无直接通路),形成一个n*n的矩阵,用以表示这个无向图。

示例:Output输出一个数,表示这个图含有连通子图的个数。

Sample Input51 0 1 0 00 1 1 1 01 1 1 1 00 1 1 1 00 0 0 0 1Sample Output自己算吧!Source∙var∙ i,j,n,ans,x:longint;∙ a:array[1..5000,0..5000] of longint;∙ b:array[1..5000] of boolean;∙procedure dfs(x:longint);∙var i:longint;∙begin∙ b[x]:=false;∙ for i:=1 to a[x,0] do if b[a[x,i]] then ∙ dfs(a[x,i]);∙end;∙∙begin∙ readln(n);∙ for i:=1 to n do∙ for j:=1 to n do begin∙ read(x);∙ if x=1 then begin∙ inc(a[i,0]); a[i,a[i,0]]:=j; ∙ end;∙ end;∙ fillchar(b,sizeof(b),true);∙ for i:=1 to n do if b[i] then begin∙ inc(ans);∙ dfs(i);∙ end;∙ writeln(ans);∙end.【图论基础】求最小生成树(prim)Time Limit:10000MS Memory Limit:65536KTotal Submit:119 Accepted:58Description求一个图的最小生成树。

Python编程实例:计算图的连通分量

Python编程实例:计算图的连通分量

06
总结与展望
总结连通分量计算的重要性和应用场景
连通分量计算是图论中的基本问题,对于理解图的结构和性质至关重 要。
连通分量计算在社交网络分析、网页排名、图像分割等领域有着广泛 的应用。
连通分量计算可以帮助我们更好地理解数据的分布和关联,从而为实 际问题提供有效的解决方案。
未来,随着图数据的不断增加,连通分量计算的重要性和应用场景将 会更加广泛。
计算连通分量:使用 networkx库的
connected_compon ents函数
输出结果:将计算 结果打印或保存到 文件中
05
连通分量计算的应用
在社交网络分析中的应用
社交网络中的连通分量:表 示社交网络中相互连接的用 户群体
连通分量的应用:分析社交 网络的结构和特性,例如找 出核心用户群、检测社交网 络中的社区结构等
添加标题
顶点表:存储图中所有顶点的信息,如顶点编号 、顶点名称等
添加标题
边表:存储图中所有边的信息,如起始顶点、终 止顶点、边的权重等
添加标题
邻接表表示法的优点:易于实现图的基本操作, 如添加顶点、删除顶点、添加边、删除边等
添加标题
邻接表表示法的缺点:占用空间较大,不适合表 示稀疏图
添加标题
Python实现图的连通分量计算时,可以使用邻接 表表示法来存储图结构,方便地进行图的遍历和 操作。
在交通运输网络中的应用
计算图的连通分量可以帮助我们理解交通运输网络的结构
通过计算连通分量,可以找出交通网络的关键节点和关键路径
在交通网络优化中,连通分量的计算可以帮助我们找到最优的交通路 线
连通分量的计算还可以帮助我们预测交通网络的拥堵情况,并采取相 应的措施进行缓解

实现连通无向图的遍历

实现连通无向图的遍历

华北水利水电学院数据结构实验报告2010~2011学年第二学期2010 级计算机专业班级:177 学号:201017724 姓名:靳清瑞一、实验题目:图遍历二、实验内容:编写程序,实现连通无向图的遍历。

实现提示:设图的顶点不超过20个,每个顶点用一个编号表示(如果一个图有n个顶点,则它们的编号分别为1,2,…,n)。

通过输入图的全部边输入一个图,每条边为一对整数,可以对边的输入顺序作某种限制。

注意,生成树的边是有向边,端点顺序不能颠倒。

三、程序源代码:#include <stdio.h>#include <stdlib.h>#define MAX_VERTEX_NUM 20typedef struct EBox{int mark;//访问标记,0未访问,1访问过int ivex,jvex;struct EBox *ilink,*jlink;}EBox;typedef struct VexBox{int data;EBox *firstedge;}VexBox;typedef struct{VexBox adjmulist[MAX_VERTEX_NUM];//0号单元未用int vexnum,edgenum;}MALGraph;int LocateVex(MALGraph &mg,int num){int i;for(i=1;i<mg.vexnum;i++){if(mg.adjmulist[i].data==num) break;}return i;}MALGraph mg;void createGraph(){printf("请分别输入图中的结点数、边数:\n");int num1,num2,lt1,lt2;scanf("%d %d",&mg.vexnum,&mg.edgenum);for(int i=1;i<=mg.vexnum;i++){mg.adjmulist[i].data=i; mg.adjmulist[i].firstedge=NULL;}for(int k=1;k<=mg.edgenum;k++){printf("请输入这个边的两个顶点:\n");scanf("%d %d",&num1,&num2); int flag=0;for(i=1;i<=mg.vexnum;i++){EBox *eb=mg.adjmulist[i].firstedge;while(eb!=NULL)if(eb->mark==1) break;eb->mark=1;if((eb->jvex==num1&&eb->ivex==num2)||(eb->jvex==num2&&eb->ivex==num1)){printf("!!!!!!!!!!这条边已经存在\n"); flag=1; break;}else{eb=eb->ilink;}if(flag==1)break;}}if(flag==1){k--; continue;}lt1=LocateVex(mg,num1); lt2=LocateVex(mg,num2);EBox *p=(EBox *)malloc(sizeof(EBox)); p->mark=0;p->ivex=lt1; p->jvex=lt2; p->ilink=NULL; p->jlink=NULL;if(mg.adjmulist[lt1].firstedge==NULL)mg.adjmulist[lt1].firstedge=p;else{EBox *q=mg.adjmulist[lt1].firstedge;if(q->jvex>p->jvex){mg.adjmulist[lt1].firstedge=p; p->ilink=q;else{EBox *r=q->ilink;while(r!=NULL){if(p->jvex<r->jvex){q->ilink=p; p->ilink=r; break;}else{q=r; r=r->ilink;}}if(r==NULL) q->ilink=p;}}if(mg.adjmulist[lt2].firstedge==NULL)mg.adjmulist[lt2].firstedge=p;else{EBox *q=mg.adjmulist[lt2].firstedge;if(q->ivex>p->ivex){mg.adjmulist[lt2].firstedge=p; p->jlink=q;}else{EBox *r=q->jlink;while(r!=NULL){if(p->ivex<r->ivex){q->jlink=p; p->jlink=r; break;}else{q=r; r=r->jlink;}}if(r==NULL) q->jlink=p;}}printf("%d-%d边创建成功!\n",num1,num2);}}typedef struct myStack{VexBox *top;VexBox *base;}myStack;int end(int a[]){int flag=0;for(int i=1;i<=mg.vexnum;i++){if(a[i]==0){flag=1; break;}}if(flag==0) return 0;if(flag==1) return 1;}void DFS(int value){for(int i=1;i<=mg.vexnum;i++){EBox *eb=mg.adjmulist[i].firstedge;while(eb!=NULL){if(eb->mark==1) eb->mark=0;eb=eb->ilink;}}myStack ms; int visited[20]; int lt;for(i=0;i<20;i++) visited[i]=0;ms.base=(VexBox *)malloc(sizeof(VexBox));ms.top=ms.base;lt=LocateVex(mg,value);EBox *p; visited[lt]=1;p=mg.adjmulist[lt].firstedge;ms.top->data=mg.adjmulist[lt].data;ms.top->firstedge=mg.adjmulist[lt].firstedge; ms.top++; VexBox *pp=NULL;while(end(visited)){printf("%d",end(visited));if(p==NULL&&pp==NULL){pp=ms.top; pp--; pp--; p=pp->firstedge;}if(p==NULL&&pp!=NULL){pp--; p=pp->firstedge;}if(p->ivex==lt){if(visited[p->jvex]==0) lt=p->jvex;else{ms.top--; p=ms.top->firstedge->ilink; ms.top++; continue;}}if(p->jvex==lt){if(visited[p->ivex]==0) lt=p->ivex;else{ms.top--; p=p->jlink; ms.top++; continue;}}ms.top->data=mg.adjmulist[lt].data;ms.top->firstedge=mg.adjmulist[lt].firstedge;visited[lt]=1; p=ms.top->firstedge; ms.top++;}int num[20];for(i=0;i<mg.vexnum;i++){ms.top--; ms.top->data=num[i];}printf("深度遍历的次序为:");for(i=mg.vexnum-1;i>=0;i--){ if(i=mg.vexnum-1) printf("%d",num[i]);else printf("->%d",num[i]);}}void main(){createGraph(); DFS(1);}三、测试结果:五、小结(包括收获、心得体会、存在的问题及解决问题的方法、建议等)这次实验遇到很多问题,利用栈或队列进行图的遍历,我显得无所适从,由于整体思路不清晰,许多判断条件不是特别明确,因此分的情况很多,实验的重复代码很多,包括用邻接多重表去建图,在添加一条边的时候,是否还应该再去判断其在链表中的位置,是插入表头,还是链表中,还是表尾。

数据结构——考试题库及答案

数据结构——考试题库及答案
设 m,n 是一棵二叉树上的两个结点,中序遍历时,n 在 m 之前的条件是__ ______。
收藏 A. n 是 m 子孙 B. n 在 m 右方 C. n 在 m 左方 D. n 是 m 祖先
回答错误!正确答案: C
具有 100 个结点的完全二叉树的深度为________。
收藏 A. 8 B. 6 C. 7 D. 9
回答错误!正确答案: C
有一个有序表{1,3,9,12,32,41,45,62,75,77,82,95,100}中折 半查找值为 82 的结点时,_______次比较后查找成功。
收藏 A. 2 B. 4 C. 1 D. 8
回答错误!正确答案: B
已知二叉树的后序遍历序列是 dabec,中序遍历序列是 debac,则它的先序遍历 序列是________。
收藏 A. 5 B. 3 C. 4 D. 6
回答错误!正确答案: A
下列函数中,时间复杂度最小的是________。
收藏 A. nlogn+5000n B. n^logn-6000n C. n^2-8000n D. 10nlogn-7000n
回答错误!正确答案: A
单链表是一种________的存储结构。
对序列{22,86,19,49,12,30,65,35,18}进行一趟排序后得到的结果为{12,86,19,4 9,22,30,65,35,18},则其使用的排序方法为( )。
收藏 A. 选择排序 B. 冒泡排序 C.
插入排序 D. 快速排序
回答错误!正确答案: A
字符串是一种特殊的线性表,其特殊性在于它的数据元素只能是______ __。
收藏 A. 15 B. 12 C. 16 D. 11
回答错误!正确答案: A
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档