Description
假设图用邻接矩阵存储。输入图的顶点信息和边信息,完成邻接矩阵的设置,并计算各顶点的入度、出度和度,并输出图中的孤立点(度为0的顶点)
–程序要求–
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求
Input
测试次数T,每组测试数据格式如下:
图类型 顶点数 (D—有向图,U—无向图)
顶点信息
边数
每行一条边(顶点1 顶点2)或弧(弧尾 弧头)信息
Output
每组测试数据输出如下信息(具体输出格式见样例):
图的邻接矩阵
按顶点信息输出各顶点的度(无向图)或各顶点的出度 入度 度(有向图)。孤立点的度信息不输出。
图的孤立点,每行一个。若没有孤立点,不输出任何信息。
Sample
#0
Input
Copy
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
Output
Copy
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
思路:
本题运用了离散数学图的知识,所以度数分为两种,入度和出度
入度:a->b,边从a进入b,所以b的入度+1, 关键字是入
出度: a->b, 边从a出发到b,所以a的出度+1 关键字是出
度数就是入度和出度的总和,入度+出度
有向图的话就是上面那种情况:
a->b
a的出度+1,b的入度+1
无向图的话:
a b意思是a->b,b->a,可以理解为存在两条边,这两条边方向相反
a的入度+1,出度+1
b的入度+1,出度+1
本题需要用到的知识点就是这么多
keys:
本题因为最开始会把所有的点给你,但是以字符串形式,而邻接矩阵用到的是整型下标,
所以可以用一个字符数组string point[]存最开始的字符串,下标就是他们的顺序
V1 V2 V3 V4 V5
0 1 2 3 4
然后如果输入 v1 v2的时候,写一个findindex()函数查找v1,v2的下标,就方便构建邻接矩阵了
可能有人会说用map,但是本题要求只能用iostream一个库
这个代码就是用来查找字符串下标的
代码:
#include <iostream>
using namespace std;
const int maxn = 1e3 + 10;
int tu[maxn][maxn];
//因为本题输入会先输入所有的点,并且是字符的,所以我写了一个strin数组,下标对应他出现的先后顺序
//如 V1 V2 V3 V4 V5
// 0 1 2 3 4
//我们构建邻接矩阵的时候需要用到整型的下标
int findindex(string ch, string point[], int n)///
{
//ch是要查找的符号,point[]是字符串数组,n是总共有多少个元素
for (int i = 0; i < n; i++)
{
if (ch == point[i])
{
return i;
}
}
}
int main()
{
int t;
cin >> t;///输入t个样例
while (t--)
{
char ch;///输入字符,判断之后的输入是有向图还是无向图
int n;
cin >> ch;
cin >> n;///输入有n个顶点
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
tu[i][j] = 0;///初始化邻接矩阵,最开始都为0
}
}
int rudu[maxn];///点的入读
int chudu[maxn];///点的出度
int sum[maxn];///点的度,就是入读和出度和
int isolat[maxn];///是孤立的点,就是度为0,入读和出度都为0
for (int i = 0; i < n; i++)
{
///初始化让上面这些度都为0
rudu[i] = 0;
chudu[i] = 0;
sum[i] = 0;
isolat[i] = 0;
}
string point[maxn];///这个是字符串数组
for (int i = 0; i < n; i++)///输入有多少个点,就是多少个字符串
{
string a;
cin >> a;
point[i] = a;
}
int m;
cin >> m;///表示有m条边
for (int i = 0; i < m; i++)
{
string a, b;
cin >> a >> b;///输入是字符串到字符串
int indexa = findindex(a, point, n);///找第一个字符串的下标
int indexb = findindex(b, point, n);///找第二个字符串的下标
tu[indexa][indexb] = 1;///构建indexa到indexb存在一条边
if (ch == 'D')///D是有向图,因为a->b,a的出度+1,b的入读+1
{
chudu[indexa]++;///a的入度+1
sum[indexa]++;///a的总度数+1
rudu[indexb]++;///b的入度+1
sum[indexb]++;///b的总度数+1
}
else//为无向图的话
{
sum[indexa]++;///a的总度数+1
sum[indexb]++;///b的总度数+1
tu[indexb][indexa] = 1;///且b也可以到a,所以构建indexb->indexa的边
}
}
///写有向图的输出;
if (ch == 'D')
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << tu[i][j] << " ";///输出有向图
}
cout << endl;
}
int k = 0;//k用来存孤立点的个数
for (int i = 0; i < n; i++)
{
if (sum[i] != 0)///输出不是孤立点
{
cout << point[i] << ":";///因为按顺序输出且要字符串
cout << " " << chudu[i] << " " << rudu[i] << " " << sum[i] << endl;//输出他的入度出度和总度数
}
if (sum[i] == 0)///找入度为0的孤立点
{
isolat[k] = i;
k++;
}
}
for (int i = 0; i < k; i++)///输出孤立点
{
cout << point[isolat[i]] << endl;
}
}
else
{ ///无向图
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << tu[i][j] << " ";///输出无向图
}
cout << endl;
}
int k = 0;///计算孤立点的个数
for (int i = 0; i < n; i++)
{
if (sum[i] != 0)
{
cout << point[i] << ": " << sum[i] << endl;///输出无向图的字符串和那个点的总度数
}
else
{
isolat[k] = i;
k++;
}
}
for (int i = 0; i < k; i++)
{
cout << point[isolat[i]] << endl;///输出孤立点。
}
}
}
return 0;
}