傳遞閉包
/**
* 傳遞閉包
*/
#include <c++/4.2.1/bits/stdc++.h>
using namespace std;
int n, m, a[111][111], flag[111];
void warshell() {
for (int j = 1; j <= n; j++) {
for (int i = 1; i <= n; i++) {
if (a[i][j]) {
for (int k = 1; k <= n; k++) {
a[i][k] = a[i][k] + a[j][k];
if (a[i][k] >= 1) a[i][k] = 1;
}
}
}
}
}
int main() {
while (cin >> n >> m) {
int x, y;
memset(a, 0, sizeof(a));
memset(flag, 1, sizeof(flag));
for (int i = 0; i < m; i++) {
cin >> x >> y;
a[x][y] = 1;
}
warshell();
int ans = 0;
for (int j = 1; j <= n; j++) {
for (int i = 1; i <= n; i++) {
if (i == j) {
if (a[i][j]) {
flag[j] = 0;
break;
}
} else if (!a[i][j] && !a[j][i]) {
flag[j] = 0;
break;
}
}
if (flag[j]) ans++;
}
cout << ans << endl;
}
return 0;
}
偏序關係
/**
* 偏序關係
* 自反性 反對稱性 傳遞性
*/
#include <c++/4.2.1/bits/stdc++.h>
using namespace std;
int n, a[111][111];
int main() {
int x, y;
while (cin >> n) {
int flag = 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> a[i][j];
}
}
for (int i = 0; i < n; i++) {
// 判斷是否 滿足 自反性
if (!a[i][i]) {
flag = 0;
break;
}
for (int j = 0; j < n; j++) {
//判斷是否滿足反對稱
if (a[i][j] && a[j][i] && i != j) {
flag = 0;
break;
}
// 判斷是否滿足傳遞
if (a[i][j]) {
for (int k = 0; k < n; k++) {
if (a[j][k] && !a[i][k]) {
flag = 0;
break;
}
}
}
}
}
printf(flag == 1 ? "yes\n" : "no\n");
}
return 0;
}
雙射。
#include <c++/4.2.1/bits/stdc++.h>
using namespace std;
int main() {
int n, m, k, a[11111], b[11111];
while (cin >> n >> m >> k) {
memset(a, -1, sizeof(a));
memset(b, -1, sizeof(b));
int x, y, num;
for (int i = 0; i < n; i++) {
cin >> num;
a[num] = 0;
}
for (int i = 0; i < m; i++) {
cin >> num;
b[num] = 0;
}
while (k--) {
cin >> x >> y;
a[x]++;
b[y]++;
}
int flag = 1;
for (int i = 1; i <= 10000; i++) {
if (a[i] > 1) {
flag = 0;
break;
}
}
for (int i = 1; i <= 10000; i++) {
if (b[i] < 1 && b[i] != -1) {
flag = 0;
break;
}
}
if (flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
羣的判定
#include <c++/4.2.1/bits/stdc++.h>
using namespace std;
int arr[110]; // 存放羣中的數據
int num[110]; // 存放逆元
int b[110]; // 存放要查詢的數據
int main() {
int n, m, q;
while (cin >> n >> m >> q) {
int flag = 0;
memset(num, -1, sizeof(num));
for (int i = 1; i <= n; i++) {
cin >> arr[i];
if (arr[i] == 0) flag = 1; // 要想G是羣 0必須存在
}
for (int i = 1; i <= q; i++) {
cin >> b[i];
}
num[0] = 0; // 0的逆元是0
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
// 在羣中找每個元素的逆元 即 元素i 和 元素j 都在羣中 且
// i+j%m==0
if (flag && (arr[i] + arr[j]) % m == 0) {
num[arr[i]] = arr[j];
num[arr[j]] = arr[i];
break;
}
}
}
for (int i = 1; i <= n; i++) {
if (num[arr[i]] == -1) { // 要想成羣 每個元素都有逆元
flag = 0;
}
}
if (!flag) {
cout << "-1" << endl;
} else {
for (int i = 1; i <= q; i++) {
cout << num[b[i]] << endl;
}
}
}
return 0;
}
補圖
#include <bits/stdc++.h>
using namespace std;
int main() {
int a[505][505], n, t;
while (cin >> n) {
int deg = 0;
int ans_max = 0;
int ans_min = 550;
for (int i = 1; i <= n; i++) {
deg = 0;
for (int j = 1; j <= n; j++) {
cin >> t;
a[i][j] = (t == 0) ? 1 : 0;
a[i][j] = (i == j) ? 0 : a[i][j];
if (a[i][j] == 1) deg++;
}
ans_max = max(ans_max, deg);
ans_min = min(ans_min, deg);
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++)
printf(j == n ? "%d\n" : "%d ", a[i][j]);
}
cout << ans_max << ' ' << ans_min << endl;
}
return 0;
}
指定長度的路徑數
#include <bits/stdc++.h>
using namespace std;
int n;
int a[505][505], b[505][505], c[505][505];
void make() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int k = 0; k < n; k++) c[i][j] += a[i][k] * b[k][j];
}
}
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) b[i][j] = c[i][j];
}
int main() {
int k;
while (cin >> n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> a[i][j];
b[i][j] = a[i][j];
}
}
cin >> k;
// k條路經 是 k-1次冪
while (--k) {
make();
}
int ans = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) ans += b[i][j];
cout << ans << endl;
}
return 0;
}
最小生成樹
#include <c++/4.2.1/bits/stdc++.h>
using namespace std;
struct node {
int parent;
int u, v, w;
} a[102400];
bool cmp(node a, node b) { return a.w < b.w; }
int find_root(int x) {
if (x == a[x].parent) {
return x;
}
return find_root(a[x].parent);
}
void union_set(int u, int v) {
int xr = find_root(u);
int yr = find_root(v);
a[xr].parent = a[yr].parent;
}
int main() {
int n, m;
while (cin >> n >> m) {
for (int i = 1; i <= m; i++) {
cin >> a[i].u >> a[i].v >> a[i].w;
}
sort(a + 1, a + m + 1, cmp);
for (int i = 1; i <= n; i++) { // 每個點的祖宗都是自己
a[i].parent = i;
}
int ans = 0; // 記錄最小的權值和
int cnt = 0; // 記錄邊的個數
for (int i = 1; i <= m; i++) {
if (find_root(a[i].u) != find_root(a[i].v)) {
cnt++;
ans += a[i].w;
union_set(a[i].u, a[i].v); // 將不形成環的兩邊連起來
}
}
// n個點 n-1條邊 否則不能構成最小生成樹
if (cnt == n - 1)
cout << ans << endl;
else
cout << "-1" << endl;
}
}