图论题型

10.1.1 度序列可简单图化

可简单图化的充要条件

例题

解法:每次度序列按非递增顺序排列,删除度最大的节点,更新其他节点的度,重新排列,继续重复上述过程。有2种不合理的情况:
(1)某次对剩下序列排序后,最大的度数(设为d1)超过了剩下的顶点数;
(2)对最大度数后面的d1个数各减1后,出现了负数。

应用Frogs’ Neighborhood

Description

未名湖附近共$N$个大小湖泊$L_1, L_2, \cdots, L_n$(其中包括未名湖),每个湖泊$L_i$里住着一只青蛙$F_i(1 \le i \le N)$。如果湖泊$L_i$和$L_j$之间有水路相连,则青蛙$F_i$和$F_j$互称为邻居。现在已知每只青蛙的邻居数目$x_1, x_2, \cdots, x_n$,请你给出每两个湖泊之间的相连关系。

Input

第一行是测试数据的组数$T(0 \le T \le 20)$。每组数据包括两行,第一行是整数$N(2 < N < 10)$,第二行是$N$个整数,$x_1, x_2,\cdots, x_n(0 \le x_i \le N)$。

Output

对输入的每组测试数据,如果不存在可能的相连关系,输出"NO"。否则输出"YES",并用$N\times N$的矩阵表示湖泊间的相邻关系,即如果湖泊$i$与湖泊$j$之间有水路相连,则第$i$行的第$j$个数字为$1$,否则为$0$。每两个数字之间输出一个空格。如果存在多种可能,只需给出一种符合条件的情形。相邻两组测试数据之间输出一个空行。

Source

POJ Monthly–2004.05.15 Alcyone@pku

参考代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

struct node {
int degree, id; // 顶点的度数和标号
} v[20];

int map[20][20];

bool cmp(node a, node b) {
return a.degree > b.degree; // 按度数降序排序
}

int main() {
int t, n, flag;
scanf("%d", &t); // 输入测试数据组数
while (t--) {
scanf("%d", &n); // 输入当前测试的顶点数量
for (int i = 0; i < n; i++) {
scanf("%d", &v[i].degree); // 输入每个顶点的度数
v[i].id = i; // 记录顶点编号
}

memset(map, 0, sizeof(map)); // 初始化邻接矩阵
flag = 1;

// 贪心算法:依次处理每个顶点,尝试连接符合要求的邻接顶点
for (int k = 0; k < n; k++) {
sort(v + k, v + n, cmp); // 对剩余的顶点按度数排序
int i = v[k].id; // 当前要连的顶点编号
int d1 = v[k].degree; // 当前节点的度数

if (d1 > n - k - 1) { // 如果当前节点的度数大于剩余顶点数,无法构图
flag = 0;
break;
}

// 从当前顶点开始,逐步连接其邻居,并减少相应邻居的度数
for (int r = 1; r <= d1 && flag; r++) {
int j = v[k + r].id; // 当前要连接的顶点编号
if (v[k + r].degree <= 0) { // 如果有度数为负的节点,说明构图失败
flag = 0;
break;
}
v[k + r].degree--; // 减少邻居的度数
map[i][j] = map[j][i] = 1; // 在邻接矩阵中标记连接
}
}

if (flag) {
printf("YES\n");
// 输出邻接矩阵
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j) printf(" ");
printf("%d", map[i][j]);
}
printf("\n");
}
} else {
printf("NO\n");
}

if (t) printf("\n"); // 如果不是最后一组数据,输出空行
}
return 0;
}

10.1.2 计算两点之间长度为k的通路数Counting Paths by Adjacency Matrices


类似求传递闭包。

10.1.3


图论题型
https://blog.yokumi.cn/2024/12/17/图论题型/
作者
Yokumi
发布于
2024年12月17日
许可协议
CC BY-NC-SA 4.0