给定一个图的邻接矩阵,请判断该图是否是连通图。连通图:任意两个顶点之间都有路径。
–程序要求–
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求
第1行输入一个整数k,表示有k个测试数据
第2行输入一个整数n,表示有n个结点
从第3行起到第n+2行输入一个邻接矩阵,其中Matrix[i,j]=1表示第i,j个结点之间有边,否则不存在边。
接下来是第2到第k个测试数据的结点数和邻接矩阵
输出Yes or No表示图是否是强连通图
2
4
0 1 1 1
1 0 1 1
1 1 0 1
1 1 1 0
7
0 1 0 0 0 0 0
0 0 1 1 0 0 0
1 0 0 0 0 0 0
1 0 1 0 0 0 0
0 0 0 0 0 1 1
0 1 0 0 0 0 0
0 0 0 1 0 1 0
Yes
No
#include
using namespace std;
const int MaxLen = 20;
int n;
int da[20][20] = {0};
int da2[20][20] = {0};
void change() {
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
da2[i][j] = da[j][i];
}
class Map {
private:
bool Visit[MaxLen];
int Matrix[MaxLen][MaxLen];
int Vexnum;
void DFS(int v);
void DFS2(int v);
int count = 0;
int c2=0;
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;
DFS(0);
if (count == Vexnum) {
change();
for (i = 0; i < Vexnum; i++)
Visit[i] = false;
DFS2(0);
if(c2==Vexnum) cout << "Yes\n";
else cout << "No\n";
} else cout << "No\n";
}
void Map::DFS2(int v) {
int w, i, k;
Visit[v] = true;
c2++;
int *AdjVex = new int[Vexnum];
for (i = 0; i < Vexnum; i++)
AdjVex[i] = -1;
k = 0;
for (i = 0; i < Vexnum; i++) {
if (da2[v][i] == 1) AdjVex[k++] = i;
}
i = 0;
for (w = AdjVex[i]; w != -1; w = AdjVex[++i]) {
if (!Visit[w]) DFS2(w);
}
delete[]AdjVex;
}
void Map::DFS(int v) {
int w, i, k;
Visit[v] = true;
count++;
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();
}
}
根据输入创建无向网。分别用Prim算法和Kruskal算法构建最小生成树。(假设:输入数据的最小生成树唯一。)
顶点数n
n个顶点
边数m
m条边信息,格式为:顶点1顶点2权值
Prim算法的起点v
输出最小生成树的权值之和
对两种算法,按树的生长顺序,输出边信息(Kruskal中边顶点按数组序号升序输出)
6
v1 v2 v3 v4 v5 v6
10
v1 v2 6
v1 v3 1
v1 v4 5
v2 v3 5
v2 v5 3
v3 v4 5
v3 v5 6
v3 v6 4
v4 v6 2
v5 v6 6
v1
15
prim:
v1 v3 1
v3 v6 4
v6 v4 2
v3 v2 5
v2 v5 3
kruskal:
v1 v3 1
v4 v6 2
v2 v5 3
v3 v6 4
v2 v3 5
#include
using namespace std;
string Name[1000];
struct Edge {
int u, v, dis;
bool operator <(const Edge& e2) const {
Edge e1 = *this;
if (e1.dis == e2.dis) {
if (e1.u == e2.u)
return e1.v > e2.v;
return e1.u > e2.u;
}
return e1.dis > e2.dis;
}
}edge[1000];
bool cmp(Edge e1, Edge e2) {
if (e1.dis == e2.dis) {
if (e1.u == e2.u)
return e1.v < e2.v;
return e1.u < e2.u;
}
return e1.dis < e2.dis;
}
int fa[1000];
int find(int x) {
if (fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
void merge(int a, int b) {
fa[find(a)] = find(b);
return;
}
int visit[1000];
int main()
{
int n, m;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> Name[i];
cin >> m;
string s1, s2;
int dis;
for (int i = 1; i <= m; i++) {
cin >> s1 >> s2 >> dis;
int u = 0, v = 0;
for (int j = 1; j <= n; j++) {
if (s1 == Name[j]) u = j;
if (s2 == Name[j]) v = j;
}
edge[i].u = u;
edge[i].v = v;
edge[i].dis = dis;
edge[i + m].u = v;
edge[i + m].v = u;
edge[i + m].dis = dis;
}
sort(edge + 1, edge + 1 + 2 * m, cmp);
int tot = 0;
for (int i = 1; i <= n; i++) {
fa[i] = i;
}
for (int i = 1; i <= 2 * m; i++) {
int u = edge[i].u, v = edge[i].v;
if (find(u) != find(v)) {
merge(u, v);
tot += edge[i].dis;
//cout << Name[u] << ' ' << Name[v] << ' '<
}
}
cout << tot << endl;
cout << "prim:" << endl;
cin >> s1;
int start;
for (int i = 1; i <= n; i++) {
if (s1 == Name[i]) {
start = i;
break;
}
}
priority_queue<Edge> q;
for (int i = 1; i <= n; i++)
visit[i] = 0;
visit[start] = 1;
for (int i = 1; i <= 2 * m; i++) {
if (edge[i].u == start) q.push(edge[i]);
}
while (!q.empty()) {
Edge t = q.top();
q.pop();
if (visit[t.v]) continue;
cout << Name[t.u] << ' ' << Name[t.v] << ' ' << t.dis << endl;
visit[t.v] = 1;
for (int i = 1; i <= 2 * m; i++) {
if (edge[i].u == t.v && !visit[edge[i].v])
q.push(edge[i]);
}
}
cout << "kruskal:" << endl;
for (int i = 1; i <= n; i++) {
fa[i] = i;
}
for (int i = 1; i <= 2 * m; i++) {
int u = edge[i].u, v = edge[i].v;
if (find(u) != find(v)) {
merge(u, v);
//tot += edge[i].dis;
cout << Name[u] << ' ' << Name[v] << ' ' << edge[i].dis << endl;
}
}
}
已知有向图,顶点从0开始编号,求它的求拓扑有序序列。
拓扑排序算法:给出有向图邻接矩阵
1.逐列扫描矩阵,找出入度为0且编号最小的顶点v
2.输出v,并标识v已访问
3.把矩阵第v行全清0
重复上述步骤,直到所有顶点输出为止
–程序要求–
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求
第一行输入一个整数t,表示有t个有向图
第二行输入n,表示图有n个顶点
第三行起,输入n行整数,表示图对应的邻接矩阵
以此类推输入下一个图的顶点数和邻接矩阵
每行输出一个图的拓扑有序序列
2
5
0 1 0 1 1
0 0 1 0 0
0 0 0 0 1
0 0 1 0 0
0 0 0 0 0
7
0 0 0 0 0 0 0
1 0 1 1 0 0 0
1 0 0 0 0 0 0
1 0 1 0 0 0 0
0 0 0 0 0 1 1
0 1 0 0 0 0 0
0 0 0 1 0 1 0
0 1 3 2 4
4 6 5 1 3 2 0
#include
using namespace std;
int Visited[100];
int a[100][100], n, k;
int JiLu[100] = {0};
void clea(int aa) {
int i;
for (i = 0; i < n; i++)
a[aa][i] = 0;
}
int findzero() {
int i, j, tag;
for (i = 0; i < n; i++) { //列数
if (!Visited[i]) {
for (j = 0, tag = 1; j < n; j++) {//行数
if (a[j][i] == 1) {
tag = 0;
break;
}
}
if (tag) {
JiLu[k++] = i;
return 1;
} else continue;
}
}
return 0;
}
int main() {
int t;
cin >> t;
while (t--) {
int i, j;
k = 0;
for(i=0;i<n;i++)
Visited[i]=0;
cin >> n;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
cin >> a[i][j];
while (findzero()) {
for (i = 0; i < k; i++, k--) {
cout << JiLu[i] << ' ';
Visited[JiLu[i]] = 1;
clea(JiLu[i]);
}
}
cout << endl;
}
}
输入无向图顶点信息和边信息,创建图的邻接矩阵存储结构,计算图的连通分量个数。
测试次数t
每组测试数据格式如下:
第一行:顶点数 顶点信息
第二行:边数
第三行开始,每行一条边信息
每组测试数据输出,顶点信息和邻接矩阵信息
输出图的连通分量个数,具体输出格式见样例。
每组输出直接用空行分隔。
3
4 A B C D
2
A B
A C
6 V1 V2 V3 V4 V5 V6
5
V1 V2
V1 V3
V2 V4
V5 V6
V3 V5
8 1 2 3 4 5 6 7 8
5
1 2
1 3
5 6
5 7
4 8
A B C D
0 1 1 0
1 0 0 0
1 0 0 0
0 0 0 0
2
V1 V2 V3 V4 V5 V6
0 1 1 0 0 0
1 0 0 1 0 0
1 0 0 0 1 0
0 1 0 0 0 0
0 0 1 0 0 1
0 0 0 0 1 0
1
1 2 3 4 5 6 7 8
0 1 1 0 0 0 0 0
1 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 1 1 0
0 0 0 0 1 0 0 0
0 0 0 0 1 0 0 0
0 0 0 1 0 0 0 0
3
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int da[100][100];
int n;
int Visited[100];
int found(string a, string* s) {
int i;
for (i = 0; i < n; i++) {
if (a == s[i]) return i;
}
}
void DFS(int v) {
int w, i, k;
Visited[v] = 1;
int* AdjVex = new int[n];
for (i = 0; i < n; i++)
AdjVex[i] = -1;
k = 0;
for (i = 0; i < n; i++) {
if (da[v][i] == 1) AdjVex[k++] = i;
}
i = 0;
for (w = AdjVex[i]; w != -1; w = AdjVex[++i]) {
if (!Visited[w]) DFS(w);
}
delete[]AdjVex;
}
void DFSTraverse() {
int i, cnt = 0;
for (i = 0; i < n; i++)
if (!Visited[i]) {
DFS(i);
cnt++;
}
cout << cnt << endl;
}
int main() {
int t;
cin >> t;
while (t--) {
int i, m, k1, k2, j;
cin >> n;
for (i = 0; i < n; i++)
Visited[i] = 0;
string* str = new string[n];
for (i = 0; i < n; i++)
cin >> str[i];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
da[i][j] = 0;
}
}
cin >> m;
for (j = 0; j < m; j++) {
string s1, s2;
cin >> s1 >> s2;
k1 = found(s1, str);
k2 = found(s2, str);
da[k1][k2] = 1;
da[k2][k1] = 1;
}
for (i = 0; i < n; i++) {
if (i < n - 1)
cout << str[i] << ' ';
else cout << str[i] << endl;
}
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (j < n - 1) cout << da[i][j] << ' ';
else cout << da[i][j] << endl;
DFSTraverse();
cout << endl;
}
}
给定有向图的邻接矩阵A,其元素定义为:若存在顶点i到顶点j的有向边则A[i,j]=1,若没有有向边则A[i,j]=0。试求A的可达闭包矩阵A*,其元素定义为:若存在顶点i到顶点j的有向路径则A*[i,j]=1,若没有有向路径则A*[i,j]=0。
第1行顶点个数n
第2行开始的n行有向图的邻接矩阵,元素之间由空格分开
有向图的可达闭包矩阵A*,元素之间由空格分开
4
0 1 0 1
0 0 1 0
0 0 0 0
0 0 0 0
0 1 1 1
0 0 1 0
0 0 0 0
0 0 0 0
#include
#include
using namespace std;
int n, mm = 0;
int data2[100][100];
int data[100][100];
int Visited[100];
void BFS(int a, int v) {
int w, i, k, u;
// data2[a][v] = 1;
int *AdjVex = new int[n];
for (i = 0; i < n; i++)
AdjVex[i] = -1;
queue<int> Q;
if (!Visited[v]) {
// Visited[v] = 1;
Q.push(v);
while (!Q.empty()) {
u = Q.front();
Q.pop();
k = 0;
for (i = 0; i < n; i++)
if (data[u][i] == 1) AdjVex[k++] = i;
i = 0;
for (w = AdjVex[i]; w >= 0; w = AdjVex[++i]) {
if (!Visited[w]) {
Visited[w] = 1;
data2[a][w] = 1;
Q.push(w);
}
}
}
}
delete[]AdjVex;
}
void BFSTraverse(int a) {
if (!Visited[a])
BFS(a, a);
}
void clea() {
int i;
for (i = 0; i < n; i++)
Visited[i] = 0;
}
int main() {
cin >> n;
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
cin >> data[i][j];
for (i = 0; i < n; i++) {
clea();
BFSTraverse(i);
}
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (j < n - 1) cout << data2[i][j] << ' ';
else cout << data2[i][j] << endl;
}