图论练习

无向图:两个有边连接的点是互通的

有向图:两个有边连接的点是不互通的,只会有一个点单向指一条边到另一个点

度:与一个节点有相连的边数量

入度:一个节点有多少条指向自己的边

出度:一个节点有多少条指向其他节点的边

最小生成树:n个结点最少需要n-1条边相连把所有点构成一个图

4408: 图的遍历

描述

 

 

图的遍历操作是从图的某一顶点出发,依次访问图中其余顶点,且每个顶点仅被访问一次。请完成无向连通图的深度优先搜索和广度优先搜索。

 

 

输入

 

 

输入数据为多组,每组数据包含多行,第一行为2个整数n(1<=n<=30),e,n为图的顶点数,e为边数,接下来是e行,每行2个整数,是一个顶点对,代表一条边所依附的两个顶点。例如,下图的输入数据为:

5 6

1 2

1 3

2 4

3 4

2 5

4 5

 

 

 

输出

 

 

每个图的深度优先搜索和广度优先搜索序列,每个序列占一行,输出的每个顶点后有一个空格。

 

 

样例输入

 

3 3
1 2
1 3
2 3
5 6
1 2
1 3
2 4
3 4
2 5
4 5

样例输出

 

1 2 3
1 2 3
1 2 4 3 5
1 2 3 4 5

提示

 

如题目描述中图所示,顶点值为整型,亦可看为顶点序号,取值从1开始。图中顶点数不超过30个,遍历时由顶点值最小的顶点开始。

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 101;
 4 int g[N][N],vis[N]; //创建二维数组地图g g[i][j]=0证明i和j不连通,=1证明i和j连通 
 5 int n,e,x,y; //n个点,e条边,x,y是连通的结点 
 6 void dfs(int x)
 7 {
 8     cout<<x<<" ";vis[x] = 1; //先输出x,并标记 
 9     for(int i=1;i<=n;i++) //遍历和x相连通的点,继续搜索 
10     {
11         if(g[x][i]==1 && vis[i]==0) //如果x和i连通,并且i没有标记过 
12         {
13             dfs(i); //以i为起点继续搜索 
14         }
15     } 
16 }
17 void bfs()
18 {
19     queue<int>q;
20     q.push(1);vis[1] = 1; //将起点1入队,并标记 
21     while(!q.empty()) //当队列不为空时 
22     {
23         int x = q.front();q.pop(); //取出队首
24         cout<<x<<" "; 
25         for(int i=1;i<=n;i++)
26         {
27             if(g[x][i]==1 && vis[i]==0) //x和i连通并且i没有标记过
28             {
29                 vis[i] = 1; //标记i,并让i入队 
30                 q.push(i);
31             } 
32         }
33     }
34 }
35 int main()
36 {
37     while(cin>>n>>e)
38     {
39         memset(g,0,sizeof(g)); //清空地图,全部不相连
40         memset(vis,0,sizeof(vis)); //清空vis数组 
41         for(int i=1;i<=e;i++) //构图,将e条边相连 
42         {
43             cin>>x>>y;
44             g[x][y] = g[y][x] = 1;//让x和y互通 
45         } 
46         dfs(1);
47         cout<<endl;
48         memset(vis,0,sizeof(vis)); 
49         bfs(); 
50         cout<<endl;
51     }
52      return 0;
53 }
复制代码

 

5664: 数据结构:有向图的出度和入度

描述

 

 

给定一个用邻接矩阵表示的有向图结构,问某个顶点的出度和入度。

 

 

输入

 

 

输入数据的第一行为n和m(n,m<=20),表示有n个顶点,接下来有n行,每行n个整数由0或1组成的有向图的邻接矩阵a,a[i][j]为0表示顶点i和j之间不连通,1表示连通(1<=i, j <=n)。

接下来一行有m个整数,每个整数是顶点的编号xi(从1~n编号)。

 

 

输出

 

 

输出有m行,每行输出指定顶点xi的出度和入度,用空格隔开。

 

 

样例输入

 

3 3
0 1 1
0 0 1
1 1 0
1 2 3

样例输出

 

2 1
1 2
2 2

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int cd[101],rd[101]; //出度cd,入度rd 
 4 int n ,m; 
 5 int main()
 6 {
 7     cin>>n>>m;
 8     for(int i=1;i<=n;i++)
 9         for(int j=1;j<=n;j++)
10         {
11             int x;cin>>x;
12             if(x) //如果x为真,那么说明i到j有一条有向边 
13             {
14                 cd[i]++; // i的出度++ 
15                 rd[j]++;// j的入度++ 
16             }
17         }
18     for(int i=1;i<=m;i++)
19     {
20         int x;cin>>x;
21         cout<<cd[x]<<" "<<rd[x]<<endl;
22     }
23      return 0;
24 }
复制代码

 

5665: 数据结构:无向图的邻接矩阵

描述

 

 

给定一个n个顶点(1到n编号)的无向图,以及若干条边,请对其构造邻接矩阵。

 

 

输入

 

输入数据有多组。

每组数据的第一行为两个正整数n和m,n表示顶点数(顶点从1到n编号),m表示边数。

接下来有m行,每行两个有正整数a和b (a和b不相等,1<=a,b<=n),表示顶点a到b有一条边。

但这些边可能有重复,只能算一次。

2<=n<=20, 0<=m<=n*(n-1)。

当m=n=0时,输入结束。

 

输出

每组输出n行n列,表示一个邻接矩阵。如果两条边有连接用1表示,否则用0表示。

样例输入

3 2
1 2
2 3
0 0

样例输出

0 1 0
1 0 1
0 1 0

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int a[101][101];
 4 int x,y,n,m;
 5 int main()
 6 {
 7     while(cin>>n>>m)
 8     {
 9         memset(a,0,sizeof(a));//初始化地图全部为0 
10         if(!n&&!m)break;
11         for(int i=1;i<=m;i++)
12         {
13             cin>>x>>y; 
14             a[x][y] = a[y][x] = 1; //无向边,所以两边都要置1 
15         }
16         for(int i=1;i<=n;i++)
17             for(int j=1;j<=n;j++)
18             {
19                 cout<<a[i][j];
20                 if(j!=n)cout<<" ";
21                 else cout<<endl;
22             }
23     }
24     
25      return 0;
26 }
复制代码

 

4670: 数据结构―有向图的最大入度和出度

描述

 

 

给定一个有向图,求顶点的最大入度和最大出度。

 

 

输入

 

 

输入数据有多组。

每组数据的第一行为两个正整数n和m,n表示顶点数(顶点从1到n编号),m表示边数。

接下来有m行,每行两个有正整数a和b (a和b不相等,1<=a,b<=n),表示顶点a到b有一条有向边。
2<=n<=20, 0<=m<=n*(n-1)。

当m=n=0时,输入结束。

 

 

输出

 

 

每组输出两个整数,即最大入度和最大出度。

 

 

样例输入

 

3 2
1 2
2 3
0 0

样例输出

 1 1
复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int rd[101],cd[101];
 4 int n,m,x,y;
 5 int main()
 6 {//4670
 7     while(cin>>n>>m)
 8     {
 9         if(!n && !m)break;
10         memset(rd,0,sizeof(rd));
11         memset(cd,0,sizeof(cd));
12         for(int i=1;i<=m;i++)
13         {
14             cin>>x>>y;
15             cd[x]++;
16             rd[y]++;
17         }
18         int maxcd = -1,maxrd = -1;//最大出度maxcd,最大入度maxrd 
19         for(int i=1;i<=n;i++)
20         {
21             maxcd = max(maxcd,cd[i]);
22             maxrd = max(maxrd,rd[i]);
23         }
24         cout<<maxrd<<" "<<maxcd<<endl;
25     }
26      return 0;
27 }
复制代码

 

3649: 欧拉回路

描述

 

 

欧拉回路是指不令笔离开纸面,可画过一个连通图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?

 

 

输入

 

 

测试输入包含若干测试用例。

每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M。

随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。

当N为0时输入结束。

 

 

 

输出

 

 

每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。

 

 

样例输入

 

3 3
1 2
1 3
2 3
3 2
1 2
2 3
0

样例输出

 

1
0

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int f[1001],d[1001];
 4 int n,m;
 5 int find(int x)
 6 {
 7     if(f[x]!=x)f[x] = find(f[x]);
 8     return f[x];
 9 }
10 void merger(int x,int y)
11 {
12     int fx = find(x);
13     int fy = find(y);
14     f[fy] = fx;
15 }
16 int main()
17 {
18     while(cin>>n,n)
19     {
20         cin>>m;
21         for(int i=1;i<=n;i++)f[i] = i;
22         memset(d,0,sizeof(d));
23         for(int i=1;i<=m;i++)
24         {
25             int x,y;cin>>x>>y;
26             d[x]++;d[y]++;
27             if(find(x)!=find(y))
28             {
29                 merger(x,y);
30             }
31         }
32         int sum = 0,k = 1;
33         for(int i=1;i<=n;i++)
34         {
35             if(f[i]==i)sum++; //寻找父节点个数 
36             if(d[i]%2!=0)k = 0; //判断第i个结点的度是否不为偶数 
37         }
38         if(sum==1&&k)cout<<1<<endl; //如果整个图只有1个父节点,并且每个点的度都是偶数,那么就是欧拉回路 
39         else cout<<0<<endl;
40     }
41      return 0;
42 }
复制代码

 

posted @   CRt0729  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示