文章目录
A. DS图—图的邻接矩阵存储及度计算
题目描述
假设图用邻接矩阵存储。输入图的顶点信息和边信息,完成邻接矩阵的设置,并计算各顶点的入度、出度和度,并输出图中的孤立点(度为0的顶点)
–程序要求–
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求
输入
测试次数T,每组测试数据格式如下:
图类型 顶点数 (D—有向图,U—无向图)
顶点信息
边数
每行一条边(顶点1 顶点2)或弧(弧尾 弧头)信息
输出
每组测试数据输出如下信息(具体输出格式见样例):
图的邻接矩阵
按顶点信息输出各顶点的度(无向图)或各顶点的出度 入度 度(有向图)。孤立点的度信息不输出。
图的孤立点。若没有孤立点,不输出任何信息。
输入样例1
2
D 5
V1 V2 V3 V4 V5
7
V1 V2
V1 V4
V2 V3
V3 V1
V3 V5
V4 V3
V4 V5
U 5
A B C D E
5
A B
A C
B D
D C
A D
输出样例1
0 1 0 1 0
0 0 1 0 0
1 0 0 0 1
0 0 1 0 1
0 0 0 0 0
V1: 2 1 3
V2: 1 1 2
V3: 2 2 4
V4: 2 1 3
V5: 0 2 2
0 1 1 1 0
1 0 0 1 0
1 0 0 1 0
1 1 1 0 0
0 0 0 0 0
A: 3
B: 2
C: 2
D: 3
E
代码
#include<iostream>
using namespace std;
int num;
int found(string a,string *s){
int i;
for(i=0;i<num;i++){
if(a==s[i]) return i;
}
}
int main() {
int T, i, bian,j;
char ch;
cin >> T;
while (T--) {
int juzhen[100][100]={0};
cin >> ch >> num;
string s1,s2;
int k1,k2;
if (ch == 'D') {
int chu[100]={0};
int ru[100]={0};
string * str = new string[num];
for (i = 0; i < num; i++)
cin >> str[i];
// cout<<str->size();
cin >> bian;
for(i=0;i<bian;i++){
cin>>s1>>s2;
k1= found(s1,str);
chu[k1]++;
k2= found(s2,str);
ru[k2]++;
juzhen[k1][k2]=1;
}
for(i=0;i<num;i++){
for( j=0;j<num;j++){
if(j<num-1) cout<<juzhen[i][j]<<' ';
else cout<<juzhen[i][j]<<endl;
}
}
string wu[100];
int wwu=0;
for(i=0;i<num;i++){
if(chu[i]+ru[i]!=0){
cout<<str[i]<<": ";
cout<<chu[i]<<' '<<ru[i]<<' '<<chu[i]+ru[i]<<endl;
}
else {
wu[wwu++]=str[i];
}
}
if(wwu){
for(i=0;i<wwu;i++)
cout<<wu[i]<<endl;
}
} else if (ch == 'U') {
int du[100]={0};
string * str = new string[num];
for (i = 0; i < num; i++)
cin >> str[i];
cin >> bian;
for(i=0;i<bian;i++){
cin>>s1>>s2;
k1= found(s1,str);
du[k1]++;
k2= found(s2,str);
du[k2]++;
juzhen[k1][k2]=1;
juzhen[k2][k1]=1;
}
for(i=0;i<num;i++){
for( j=0;j<num;j++){
if(j<num-1) cout<<juzhen[i][j]<<' ';
else cout<<juzhen[i][j]<<endl;
}
}
string wu[100];
int wwu=0;
for(i=0;i<num;i++){
if(du[i]!=0){
cout<<str[i]<<": ";
cout<<du[i]<<endl;
}
else {
wu[wwu++]=str[i];
}
}
if(wwu){
for(i=0;i<wwu;i++)
cout<<wu[i]<<endl;
}
}
}
return 0;
}
B. 图综合练习–构建邻接表
题目描述
已知一有向图,构建该图对应的邻接表。
邻接表包含数组和单链表两种数据结构,其中每个数组元素也是单链表的头结点,数组元素包含两个属性,属性一是顶点编号info,属性二是指针域next指向与它相连的顶点信息。
单链表的每个结点也包含两个属性,属性一是顶点在数组的位置下标,属性二是指针域next指向下一个结点。
输入
第1行输入整数t,表示有t个图
第2行输入n和k,表示该图有n个顶点和k条弧。
第3行输入n个顶点。
第4行起输入k条弧的起点和终点,连续输入k行
以此类推输入下一个图
输出
输出每个图的邻接表,每行输出格式:数组下标 顶点编号-连接顶点下标-…-^,数组下标从0开始。
具体格式请参考样例数据,每行最后加入“^”表示NULL。
输入样例1
1
5 7
A B C D E
A B
A D
A E
B D
C B
C E
E D
输出
0 A-1-3-4-^
1 B-3-^
2 C-1-4-^
3 D-^
4 E-3-^
代码
#include<iostream>
int n;
using namespace std;
int found(char a,char s[100][100]){
int i;
for(i=0;i<n;i++){
if(a==s[i][0]) return i;
}
}
int main(){
int t,k,i;
cin>>t;
while(t--){
cin>>n>>k;
char ch1,ch2;
char da[100][100];
int k1,k2;
int num[100]={0};
for(i=0;i<n;i++)
cin>>da[i][0];
for(i=0;i<k;i++)
{
cin>>ch1>>ch2;
k1= found(ch1,da);
k2= found(ch2,da);
da[k1][num[k1]+1]=k2+'0';
num[k1]++;
}
for(i=0;i<n;i++){
cout<<i<<' '<<da[i][0];
for(int j=1;j<=num[i];j++)
cout<<'-'<<da[i][j];
cout<<"-^\n";
}
}
}
C. DS图遍历–深度优先搜索
题目描述
给出一个图的邻接矩阵,对图进行深度优先搜索,从顶点0开始
以下代码框架仅供参考,同学们可在理解的基础上自行设计算法,不强制要求和框架相同
注意:图n个顶点编号从0到n-1
代码框架如下:
输入
第一行输入t,表示有t个测试实例
第二行输入n,表示第1个图有n个结点
第三行起,每行输入邻接矩阵的一行,以此类推输入n行
第i个结点与其他结点如果相连则为1,无连接则为0,数据之间用空格隔开
以此类推输入下一个示例
输出
每行输出一个图的深度优先搜索结果,结点编号之间用空格隔开
输入样例1
2
4
0 0 1 1
0 0 1 1
1 1 0 1
1 1 1 0
5
0 0 0 1 1
0 0 1 0 0
0 1 0 1 1
1 0 1 0 0
1 0 1 0 0
输出
0 2 1 3
0 3 2 1 4
代码
#include<iostream>
using namespace std;
const int MaxLen=20;
int n;
int da[20][20]={0};
class Map{
private:
bool Visit[MaxLen];
int Matrix[MaxLen][MaxLen];
int Vexnum;
void DFS(int v);
public:
void SetMatrix(int vnum,int mx[MaxLen][MaxLen]);
void DFSTraverse();
};
void Map::SetMatrix(int vnum, int (*mx)[20]) {
int i,j;
Vexnum=vnum;
for(i=0;i<MaxLen;i++)
for(j=0;j<MaxLen;j++)
Matrix[i][j]=0;
for(i=0;i<Vexnum;i++)
for(j=0;j<Vexnum;j++)
Matrix[i][j]=mx[i][j];
}
void Map::DFSTraverse() {
int i;
for(i=0;i<Vexnum;i++)
Visit[i]=false;
for(i=0;i<Vexnum;i++)
if(!Visit[i]) DFS(i);
cout<<endl;
}
void Map::DFS(int v) {
int w,i,k;
Visit[v]= true;
cout<<v<<' ';
int *AdjVex=new int [Vexnum];
for(i=0;i<Vexnum;i++)
AdjVex[i]=-1;
k=0;
for(i=0;i<Vexnum;i++){
if(Matrix[v][i]==1) AdjVex[k++]=i;
}
i=0;
for(w=AdjVex[i];w!=-1;w=AdjVex[++i]){
if(!Visit[w]) DFS(w);
}
delete []AdjVex;
}
int main(){
int t,i,j;
cin>>t;
while(t--){
cin>>n;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
cin>>da[i][j];
Map p;
p.SetMatrix(n,da);
p.DFSTraverse();
}
}
D. DS图遍历–广度优先搜索
题目描述
给出一个图的邻接矩阵,对图进行深度优先搜索,从顶点0开始
以下代码框架仅供参考,同学们可在理解的基础上自行设计算法,不强制要求和框架相同
注意:图n个顶点编号从0到n-1
代码框架如下:
输入
第一行输入t,表示有t个测试实例
第二行输入n,表示第1个图有n个结点
第三行起,每行输入邻接矩阵的一行,以此类推输入n行
第i个结点与其他结点如果相连则为1,无连接则为0,数据之间用空格隔开
以此类推输入下一个示例
输出
每行输出一个图的广度优先搜索结果,结点编号之间用空格隔开
输入样例1
2
4
0 0 1 1
0 0 1 1
1 1 0 1
1 1 1 0
5
0 0 0 1 1
0 0 1 0 0
0 1 0 1 1
1 0 1 0 0
1 0 1 0 0
输出
0 2 3 1
0 3 4 2 1
代码
#include<bits/stdc++.h>
using namespace std;
const int MaxLen = 20;
int n;
int da[20][20] = {0};
class Map {
private:
bool Visit[MaxLen];
int Matrix[MaxLen][MaxLen];
int Vexnum;
void BFS(int v);
public:
void SetMatrix(int vnum, int mx[MaxLen][MaxLen]);
void BFSTraverse();
};
void Map::SetMatrix(int vnum, int (*mx)[20]) {
int i, j;
Vexnum = vnum;
for (i = 0; i < MaxLen; i++)
for (j = 0; j < MaxLen; j++)
Matrix[i][j] = 0;
for (i = 0; i < Vexnum; i++)
for (j = 0; j < Vexnum; j++)
Matrix[i][j] = mx[i][j];
}
void Map::BFSTraverse() {
BFS(0);
}
void Map::BFS(int v) {
int w, u;
int i, k;
int *AdjVex = new int[Vexnum];
for (i = 0; i < Vexnum; i++)
AdjVex[i] = -1;
queue<int> Q;
for (i = 0; i < Vexnum; i++)
Visit[i] = false;
for (v = 0; v < Vexnum; v++) {
if (!Visit[v]) {
Visit[v] = true;
cout << v << ' ';
Q.push(v);
while (!Q.empty()) {
u = Q.front();
Q.pop();
k = 0;
for (i = 0; i < Vexnum; i++) {
if (Matrix[u][i] == 1) AdjVex[k++] = i;
}
i = 0;
for (w = AdjVex[i]; w >= 0; w = AdjVex[++i]) {
if (!Visit[w]) {
Visit[w] = true;
cout << w << ' ';
Q.push(w);
}
}
}
}
}
cout << endl;
}
int main() {
int t, i, j;
cin >> t;
while (t--) {
cin >> n;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
cin >> da[i][j];
Map p;
p.SetMatrix(n, da);
p.BFSTraverse();
}
}
E. DS图—图非0面积
题目描述
编程计算由"1"围成的下列图形的面积。面积计算方法是统计"1"所围成的闭合曲线中"0"点的数目。如图所示,在10*10的二维数组中,"1"围住了15个点,因此面积为15。
提示:queue
输入
测试次数t
每组测试数据格式为:
数组大小m,n
一个由0和1组成的m*n的二维数组
输出
对每个二维数组,输出符号"1"围住的"0"的个数,即围成的面积。假设一定有1组成的闭合曲线,但不唯一。
输入样例1
2
10 10
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 0 0 0
0 0 0 0 1 0 0 1 0 0
0 0 0 0 0 1 0 0 1 0
0 0 1 0 0 0 1 0 1 0
0 1 0 1 0 1 0 0 1 0
0 1 0 0 1 1 0 1 1 0
0 0 1 0 0 0 0 1 0 0
0 0 0 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0
5 8
0 1 1 0 0 1 1 0
1 0 1 0 1 0 0 1
0 1 0 1 0 0 1 0
0 1 0 0 1 1 1 0
0 0 0 0 0 0 0 0
输出
15
5
代码
#include<iostream>
#include<queue>
using namespace std;
class Map
{
public:
int graph[100][100];
int m,n;
void initialize()
{
for(int i=0;i<=m+1;i++)//先将二维数组初始化为0
for(int j=0;j<=n+1;j++)
graph[i][j]=0;
cin >> m >> n;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
cin >> graph[i][j];
}
void BFS()
{
int x=0,y=0;
queue<int> Qx,Qy;
Qx.push(x);
Qy.push(y);
graph[x][y]=1;
int nx[4]={-1,0,1,0};//在for循环中分别对应上下左右的结点
int ny[4]={0,1,0,-1};
while(!Qx.empty()){
for(int i=0;i<4;i++){//判断上下左右的结点是否合格
if(Qx.front()+nx[i]>=0&&Qx.front()+nx[i]<=m+1&&Qy.front()+ny[i]>=0&&Qy.front()+ny[i]<=n+1&&graph[Qx.front()+nx[i]][Qy.front()+ny[i]]==0){
Qx.push(Qx.front()+nx[i]);
Qy.push(Qy.front()+ny[i]);
graph[Qx.front()+nx[i]][Qy.front()+ny[i]]=1;//合格就变成墙
}
}
Qx.pop();
Qy.pop();
}
}
void print()
{
int num=0;
for(int i=0;i<=m;i++)
for(int j=0;j<=n;j++)
if(graph[i][j]==0)num++;
cout<<num<<endl;
}
};
int main()
{
int t;
cin >> t;
while(t--)
{
Map mygraph;
mygraph.initialize();
mygraph.BFS();
mygraph.print();
}
return 0;
}